![]()  | 
		     | 
	
Задавайте вопросы, мы ответим
Вы не зашли.
Страниц: 1
Пример,
Select *From films f, zanr_film zf where flag_film=1 and zf.id_film=f.id_film and id_zanr=15 order by name_film
Выполняется за 0.3 сек.
Select *From films f, zanr_film zf where flag_film=1 and zf.id_film=f.id_film and id_zanr=5 order by name_film
выполняется за 0.06 сек.
Разница в запросах id_zanr
В первом случае записей примерно 300 штук, во втором более 3.000
При этом, чем меньше записей в результате поиска, тем дольше работает запрос.
Отредактированно humbert (04.05.2010 15:09:25)
Неактивен

А EXPLAIN от запросов покажите, пожалуйста?
Ну и надо понимать, что при таких скоростях ответа могут влиять разнообразные
факторы (загруженность машинки, загружена ли табличка в память, query cache,
еще какие-то).
Неактивен
Первый запрос, где меньше записей (id_zanr=15)
id select_type table type possible_keys key key_len ref rows Extra
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE f ref PRIMARY,name_film_2,view_film,date_public,duration... name_film_2 4 const 16569 Using where
1 SIMPLE zf eq_ref id_zanr_2 id_zanr_2 8 zxkino.f.id_film,const 1 Using index
Второй запрос, где записей больше (id_zanr=5)
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE f ref PRIMARY,name_film_2,view_film,date_public,duration... name_film_2 4 const 16569 Using where
1 SIMPLE zf eq_ref id_zanr_2 id_zanr_2 8 zxkino.f.id_film,const 1 Using index
CREATE TABLE zanr_film (
id_zanr int(11) NOT NULL,
id_film int(11) NOT NULL,
UNIQUE KEY id_zanr_2 (id_film,id_zanr)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Если убрать KEY id_zanr_2, то запрос, где записей меньше выполняется быстрее, а там, где их больше, медленее
Отредактированно humbert (04.05.2010 15:48:55)
Неактивен

У Вас ключ неудачный — приходится бежать по всей табличке и выискивать значения.
Попробуйте сделать ключики (id_zanr) на табличке zanr_film и ключик (id_film, name_film)
на films.
Ну и если у Вас есть уникальный ключ над not-null полями, то стоит, наверное, его
назвать primary key ![]()
Неактивен
Спасибо за помощь, но ситуация такая же. Играл с индексами, разные ставил. Либо быстро выбираются те, которых меньше, либо наоборот. Но вот чтобы оба варианта работало не получилось.
Неактивен

Без explain все равно ничего сделать не удастся ![]()
Неактивен
Да explain показывает одно и тоже на обоих запросах.
Неактивен

Приходит человек к врачу:
— Доктор, у меня сын и дочка — у обоих красные пятна по лицу пошли!
— Покажите их.
— Они дома остались, я не решился их с собой взять.
— Ну, тогда я ничего сказать не могу.
— Но у них же у обоих одинаковые красные пятна по лицу!
Да, у Вас две одинаково плохие выборки. И я с ними ничего сделать не могу,
пока не увижу симптомы. Даже если они одинаковые ![]()
Неактивен
Спасибо за помощь и за потраченное время.
Если у Вас есть еще время и желание помочь (понять), то вот сами таблицы
CREATE TABLE films (
id_film int(11) NOT NULL auto_increment,
name_film varchar(255) NOT NULL,
eng_film varchar(255) NOT NULL,
duration_film int(11) NOT NULL,
opis_film text,
reiting_imdb float NOT NULL,
year_film int(4) NOT NULL,
trailer_url varchar(255) NOT NULL,
slug_film varchar(255) NOT NULL,
code_char_film int(11) default NULL,
description_film text,
door_title varchar(255) NOT NULL,
door_keyword varchar(255) NOT NULL,
door_description text,
door_opis text,
view_film int(11) NOT NULL,
title_film varchar(255) NOT NULL,
main_img varchar(255) NOT NULL,
trailer_width int(11) NOT NULL,
trailer_height int(11) NOT NULL,
date_public int(11) NOT NULL,
reiting_kinopoisk float NOT NULL,
reiting_site float NOT NULL,
keyword_film varchar(255) NOT NULL,
peremen_film text NOT NULL,
flag_film int(1) NOT NULL,
PRIMARY KEY (id_film),
UNIQUE KEY slug_film (slug_film,code_char_film),
KEY name_film (name_film)
) ENGINE=MyISAM AUTO_INCREMENT=16574 DEFAULT CHARSET=utf8;
CREATE TABLE zanr_film (
id_zanr int(11) NOT NULL,
id_film int(11) NOT NULL,
PRIMARY KEY (id_film,id_zanr)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
В films более 16.000 записей, в zanr_film более 25000, при этом id_zanr не более 25 штук всего. У некоторых фильмов несколько жанров. Из 25 жанров есть такие, у которых всего 24 фильма, а есть такие, у которых более 4.000 фильмов.
Нужно вывести список фильмов определенных жанров, и вот тут то и есть тормоза. Если стоит index в zanr_film по id_film, то быстрее всего выводится список для жанра, который имеет наибольшее количество фильмов. Если индекс отсутствует, то жанр с наименьшим количеством будет быстрее обрабатываться.
Неактивен

Ахаа, вот и начинает проясняться ![]()
Проблема такая: Вы пытаетесь выбрать бОльшую часть таблицы. Это практически
всегда приводит к тому, что таблица сканируется целиком на предмет нужных
строк, полностью игнорируя любые индексы. Если бы Вы туда ввели разумный
LIMIT (который Вам в любом случае нужен), то ситуация была бы совсем другой ![]()
Ситуация «маленькая выборка»: индекс на zanr_film(id_zanr) позволит выбрать id
фильмов, а потом выбрать из основной таблицы соответствующее небольшое
количество строк.
Ситуация «большая ограниченная выборка»: индекс на film (flag_film, name_film)
позволит выбирать данные в нужном порядке, учитывая наличие флага. Каждую
выбранную таким образом строчку нужно будет сверять с нужным жанром, но в
случае с LIMIT — это будет более простая операция.
Неактивен
Не совсем врубаюсь, можно языком для даунов?![]()
Мне 2 запроса делать к БД: сначала id_film из таблицы жанров, а потом конкретные фильмы?
Неактивен

Добавьте индекс
ALTER TABLE zanr_film ADD INDEX (id_zanr) — это увеличит скорость работы в случае,
если выбирается небольшое количество строк.
Добавьте LIMIT 10 в конце запроса, чтобы работало всегда быстро ![]()
Неактивен
Вот так? 
Select *From films f, zanr_film zf where flag_film=1 and zf.id_film=f.id_film and id_zanr=5 order by name_film Limit 10
Если так, то выполняется 0.5 сек.![]()
Да и Limit 10 мне не особо нужен, т.к. осуществляю постраничный вывод фильмов, т.е. используется и Limit 10000, 90
А с индексами пробовал по разному, нашел закономерность, если много фильмов в жанре, то ставим индекс на id_film
Alter Table zanr_film enable keys
, 
если мало, то индекс убираем. 
Alter Table zanr_film disable keys
Индекс стоит на id_film в zanr_film. Работает быстро. 
Но опять уперся в Limit, если "Limit 0,90", то быстро (0.06 сек.) , если же "Limit 4734, 90", то примерно 1 сек. запрос выполняется.
Еще раз спасибо за помощь, за 10 лет, что работаю типа программистом, первый раз взялся изучать оптимизацию mysql
Неактивен

Ну, если Вы выбираете 10к строк, то половина секунды — неплохой результат ![]()
Добавить-убрать индекс — это операция, которую перед запросом делать не надо,
надо добавить его — и он будет работать для коротких запросов.
LIMIT 10000, 90 — это очень очень очень плохой запрос. Я говорил «очень»? К
счастью, люди не смотрят больше 3-4 страниц обычно (и, если Вы хотите их зас-
тавить это делать, то лучше подумайте, не сделать ли более глубокий рубрикатор).
Неактивен
Спасибо, будем думать дальше, как оптимизировать работу. Возможно будет лучшим предусмотреть кеширование данных в файл и выдавать кеш. Правда тут возникает проблема актуальности данных, но что-нить придумаю.
Спасибо за помощь![]()
Неактивен

Ну, можете настроить Query Cache — тогда он будет инвалидироваться автоматом.
Для популярных одиночных запросов — очень даже полезная штука.
Неактивен
Спасибо еще раз. Низко кланяюсь.
Неактивен
Страниц: 1