SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 17.03.2009 05:15:28

Proger
Активист
Откуда: Санкт-Петербург
Зарегистрирован: 04.09.2008
Сообщений: 172

Этот любимый filesort

Здраствуйте.
Уже 2 дня бьюсь никак не могу поставить правильный индекс или изменить запрос.

SELECT `from` , `text` , `date` FROM .`history` WHERE `mid` = 121 AND (`from` =617 OR `for` =617) AND `date` > NOW( )  - INTERVAL 15 DAY ORDER BY `date` ASC


EXPLAIN:
id     select_type     table     type     possible_keys     key     key_len     ref     rows     Extra
1     SIMPLE     history     ref     from,mid     mid     8     const     2252     Using where; Using filesort

Структура таблицы:
CREATE TABLE `history` (
  `mid` bigint(12) NOT NULL,
  `unid` bigint(12) NOT NULL,
  `from` int(8) NOT NULL,
  `for` int(8) NOT NULL,
  `text` text NOT NULL,
  `date` datetime NOT NULL,
  `fav` enum('da','net') NOT NULL,
  KEY `from` (`mid`,`from`,`for`,`date`),
  KEY `mid` (`mid`,`unid`)
) ENGINE=MyISAM  DEFAULT CHARSET=cp1251;

#для примера немного строк, чтобы было понятней назначение полей


INSERT INTO `history` VALUES(121, 27, 121, 617,  'Чё-то текста твоего не видать = (', '2008-12-01 18:08:32', 'net');
INSERT INTO `history` VALUES(617, 27, 617, 121, 'Чё-то текста твоего не видать = (', '2008-12-01 18:08:32', 'net');
INSERT INTO `history` VALUES(121, 28, 121, 617, 'А-а-а-а! "Проверка', '2008-12-01 18:09:44', 'net');
INSERT INTO `history` VALUES(617, 28, 617, 121, 'А-а-а-а! "Проверка', '2008-12-01 18:09:44', 'net');
INSERT INTO `history` VALUES(121, 29, 121, 617, 'какого моего текста?', '2008-12-01 19:10:39', 'net');
INSERT INTO `history` VALUES(617, 29, 617, 121, 'какого моего текста?', '2008-12-01 19:10:39', 'net');


И самое противное что filesort отнюдь не маленькой таблички происходит. Благо пока запрос в среднем занимает несколько секунд, а что будет дальше, я боюсь себе представить. Сам же запрос выгружает историю переписки за энный период и выдаёт ввиде сгенерированного файла, потому вариант выводить меньше и подобные - не рассматриваю. Почему данные дублируются прошу тоже не спрашивать - особенности приложения smile

Собственно что не так, как бороться? Помогите пожалуйста.

Отредактированно Proger (17.03.2009 05:19:44)

Неактивен

 

#2 17.03.2009 11:07:02

coin
Гуру
Зарегистрирован: 15.07.2008
Сообщений: 66

Re: Этот любимый filesort

`from` =617 OR `for` =617
Вот такую конструкцию в индекс не всунешь.

Здесь "или" мешает использовать левый префикс индекса, т.к. для проверки условия может использоваться либо `FROM` (тогда результат уже не зависит от `for` и он не используется), либо используется `for` (тогда не используется `FROM`), в любом случае получится дырка.
Здесь, наверно, самый оптимальный индекс: (`mid`, `date`)

Неактивен

 

#3 17.03.2009 20:17:52

Proger
Активист
Откуда: Санкт-Петербург
Зарегистрирован: 04.09.2008
Сообщений: 172

Re: Этот любимый filesort

Спасибо за ответ. Тогда добавлю просто ещё одно поле для индефикации. Ибо индекс (`mid`, `date`) не особо помог. Сделаю всё типа where `mid` = 100 AND `sid` = 105 чтобы не было OR. Спасибо не знал, что так нельзя, чтобы использывать преимущества индексов.

Неактивен

 

#4 18.03.2009 11:41:49

Magz
Гуру
Откуда: Москва
Зарегистрирован: 18.09.2007
Сообщений: 112

Re: Этот любимый filesort

У Вас поле MID входит в два индекса, я бы рекомендовал оставить только один.
А для того, чтобы убрать filesort именно в Вашем запросе попробуйте убрать сортировку результата - сразу файлсорт уйдет. Поэтому, я бы создал индекс на поле `DATE` и использовал бы именно его в запросе:

explain SELECT `FROM` , `TEXT` , `DATE` FROM .`history` use index(date) WHERE `MID` = 121 AND (`FROM` =617 OR `for` =617) AND `DATE` > NOW( )  - INTERVAL 15 DAY ORDER BY `DATE` ASC
id     select_type     table     type     possible_keys     key     key_len     ref     rows     Extra
1     SIMPLE     history     range     DATE     DATE     8     NULL     1     Using where

Как уже отметил coin, для операции "OR" индекс все равно не используется, а по дате он будет использоваться и в WHERE и в ORDER BY.

Отредактированно Magz (18.03.2009 11:43:05)

Неактивен

 

#5 21.03.2009 05:28:48

Diter
Участник
Зарегистрирован: 21.03.2009
Сообщений: 5

Re: Этот любимый filesort

А не надо вообще боятся этого filesort. Тем более, что

Proger написал:

...Благо пока запрос в среднем занимает несколько секунд

Как правильно было сказано

Magz написал:

...А для того, чтобы убрать filesort именно в Вашем запросе попробуйте убрать сортировку результата

В данном случае filesort - это обыкновенная сортировка, вызванная ORDER BY.

Прочитано здесь: http://www.mysqlperformanceblog.com/200 … -in-mysql/

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson