SQLinfo.ru - Все о MySQL

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

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

Вы не зашли.

#1 02.05.2012 11:34:02

pomuk123
Участник
Зарегистрирован: 23.11.2010
Сообщений: 11

Помогите создать нужный индекс для запроса

Доброе время суток.
Ребят, помогите создать индекс к запросу. Вот уже целый день мучаюсь и никак не получается. Перепробовал кучу вариантов. Все время присутствует "filesort".


Запрос

explain SELECT * FROM `gift` WHERE whom=123 AND action='now' ORDER BY visit, date DESC LIMIT 5, 5


Результат

id    select_type    table    type    possible_keys    key    key_len    ref    rows    Extra
1    SIMPLE    gift    ALL    ix_list    NULL    NULL    NULL    1057    Using where; Using filesort


Структура таблицы

CREATE TABLE `gift` (
 `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
 `who` int(10) unsigned NOT NULL,
 `whom` int(10) unsigned NOT NULL,
 `eventName` varchar(255) NOT NULL,
 `eventID` int(10) unsigned NOT NULL,
 `date` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
 `action` enum('now','later','notsent') NOT NULL,
 `visit` tinyint(1) NOT NULL,
 PRIMARY KEY (`id`),
 KEY `ix_list` (`whom`,`action`,`visit`,`date`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8

Неактивен

 

#2 02.05.2012 11:42:00

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Помогите создать нужный индекс для запроса

Сейчас вообще не используется индекс, согласно EXPLAIN. Возможно, слишком мало записей в таблице - добавьте записей до реалистичного количества.

Неактивен

 

#3 02.05.2012 11:56:44

pomuk123
Участник
Зарегистрирован: 23.11.2010
Сообщений: 11

Re: Помогите создать нужный индекс для запроса

Добавил полтары тысячи записей

Запрос

explain SELECT * FROM `gift` WHERE whom=123 AND action='now' ORDER BY visit, date DESC LIMIT 5, 5


Результат
id    select_type    table    type    possible_keys    key    key_len    ref    rows    Extra
1    SIMPLE    gift    ALL    ix_list    NULL    NULL    NULL    1057    Using where; Using filesort

Запрос без "DESC" после `date`
explain SELECT * FROM `gift` WHERE whom=123 AND action='now' ORDER BY visit, date LIMIT 5, 5


Результат
id    select_type    table    type    possible_keys    key    key_len    ref    rows    Extra
1    SIMPLE    gift    index    ix_list    ix_list    10    NULL    10    Using where

Неактивен

 

#4 02.05.2012 12:02:26

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Помогите создать нужный индекс для запроса

В первом результате отображается 1057 записей, значит это еще не расширенная таблица.

Неактивен

 

#5 02.05.2012 12:19:03

pomuk123
Участник
Зарегистрирован: 23.11.2010
Сообщений: 11

Re: Помогите создать нужный индекс для запроса

Извиняюсь, не совсем понял, что значит расширенная таблица?
2 запроса, написанных в предыдущем посте, были сделаны с уже заполненной таблицей.

Неактивен

 

#6 02.05.2012 12:20:52

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Помогите создать нужный индекс для запроса

Он пишет Type=ALL и rows=1057, значит в таблице всего 1057 строк.

Неактивен

 

#7 02.05.2012 14:00:00

pomuk123
Участник
Зарегистрирован: 23.11.2010
Сообщений: 11

Re: Помогите создать нужный индекс для запроса

Так, еще разок все перепроверил. В таблице 1824 записи.
Индекс, который более мение подходит для меня "без DESC после `date`" - KEY `ix_list` (`whom`,`visit`,`date`)

Explain запроса, для которого я подбираю индекс

explain SELECT * FROM `gift` WHERE whom=123 AND action='now' ORDER BY visit, date DESC LIMIT 5, 5



+----+-------------+-------------+------+---------------+-------------+---------+-------+------+-----------------------------+
| id | select_type | table       | type | possible_keys | key         | key_len | ref   | rows | Extra                       |
+----+-------------+-------------+------+---------------+-------------+---------+-------+------+-----------------------------+
|  1 | SIMPLE      | gift          | ref  | ix_list   | ix_list | 8       | const |  873 | Using where; Using filesort |
+----+-------------+-------------+------+---------------+-------------+---------+-------+------+-----------------------------+

без "DESC" после `date` - все супер
+----+-------------+-------------+------+---------------+-------------+---------+-------+------+-------------+
| id | select_type | table       | type | possible_keys | key         | key_len | ref   | rows | Extra       |
+----+-------------+-------------+------+---------------+-------------+---------+-------+------+-------------+
|  1 | SIMPLE      | gift         | ref  | ix_list   | ix_list | 8       | const |  873 | Using where |
+----+-------------+-------------+------+---------------+-------------+---------+-------+------+-------------+

Отредактированно pomuk123 (02.05.2012 14:01:03)

Неактивен

 

#8 02.05.2012 14:28:55

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Помогите создать нужный индекс для запроса

1824 записи - это тоже немного. Лучше сделать хотя бы 10 тысяч. Еще подозрительно, что rows=873, то есть приходится перебирать 873 строки. Наверное таблица наполнена не совсем реалистично - многие данные повторяются.

Вы пишете, что все супер, глядя на Extra, но длина используемого индекса в обоих случаях 8 байт, то есть используется одна и та же часть (`whom`,`visit`). Попробуйте с таким двойным индексом, будет ли такой же ответ. Когда в индексе было поле action, то длина используемого индекса была 10 байт. Попробуйте на большой таблице сделать профилирование запросов http://webew.ru/articles/2732.webew

Неактивен

 

#9 02.05.2012 14:59:05

pomuk123
Участник
Зарегистрирован: 23.11.2010
Сообщений: 11

Re: Помогите создать нужный индекс для запроса

Спасибо за ответ. Пошел изучать данную статью.

Неактивен

 

#10 02.05.2012 16:33:04

pomuk123
Участник
Зарегистрирован: 23.11.2010
Сообщений: 11

Re: Помогите создать нужный индекс для запроса

В общем.
1. Индекс по двум полям перестал работать и для запроса без "DESC".

2. Написал пхп-скрипик, который засунул мне 1.1 миллиона записей в таблицу. Записи были максимально рандомизированны, чтобы приблизть таблицу к реальной.

Ничего не изманилось. Также присутсвует "филесорт".
Самая "жрущая" опция из профилирования, где "филесорт"
| Sorting result                 | 7.637742 |

А там , где нету "DESC" и индекс сработал на ура -
| Sorting result                 | 0.000011 |

В общем, вывод - нужно правильно составить индекс.

Неактивен

 

#11 02.05.2012 21:12:25

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Помогите создать нужный индекс для запроса

Странно все это - в MySQL индексы двунаправленные, им все равно по возрастанию или убыванию сортировать. Но если есть практическая разница, значит какая-то асимметрия в реализации или бага.

Неактивен

 

#12 03.05.2012 10:32:00

pomuk123
Участник
Зарегистрирован: 23.11.2010
Сообщений: 11

Re: Помогите создать нужный индекс для запроса

А если убрать двойную сортиртовку, т.е вместо "ORDER BY visit, date DESC", написать "ORDER BY date DESC,а ключ сделать ix_list(`whom`, `date) - то тогда индекс сробатывает и нету филесорт, независимо от вида сортировки.

Отредактированно pomuk123 (03.05.2012 10:32:27)

Неактивен

 

#13 04.05.2012 22:48:09

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Помогите создать нужный индекс для запроса

Не двунаправленные индексы, к сожалению. Ну то есть будет работать
ORDER BY visit DESC, date DESC, но не в разных направлениях, увы.

Обычно в этом месте применяют какие-то костыли. Например, можно
хранить [-visit] вместо [visit], и тогда сортировка будет правильной.

Неактивен

 

#14 05.05.2012 20:50:42

LazY
_cмельчак
MySQL Authorized Developer and DBA
Зарегистрирован: 02.04.2007
Сообщений: 849

Re: Помогите создать нужный индекс для запроса

Но хотя бы для первой колонки индекс будет использоваться?

Неактивен

 

#15 05.05.2012 21:09:42

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Помогите создать нужный индекс для запроса

LazY написал:

Но хотя бы для первой колонки индекс будет использоваться?

Для этого нужно знать какой путь выбирает MySQL - сортировка всего файлсортом или сортировка частично отсортированных данных кусочками (что не всегда даст выйгрыш, но теоретически может дать). Скорее всего первое, так как это не требует реализации дополнительного алгоритма. Наверное, это можно проверить в версии 5.6, используя Optimizer tracing, http://forge.mysql.com/wiki/MySQL_Inter … er_tracing

Неактивен

 

#16 09.05.2012 00:07:49

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Помогите создать нужный индекс для запроса

Посмотрите в сторону MariaDB
http://kb.askmonty.org/en/alter-table
index_col_name:
    col_name [(length)] [ASC | DESC]

В ней возможно создать KEY(`whom` ASC, `visit` ASC, `date` DESC).

Неактивен

 

#17 10.05.2012 10:38:55

pomuk123
Участник
Зарегистрирован: 23.11.2010
Сообщений: 11

Re: Помогите создать нужный индекс для запроса

у нас проект на Mysql, поэтому нету возможности перейти на другую базу данных.
Вобщем решил проблему методом костыля, как советовали в предыдущих постах

Неактивен

 

#18 10.05.2012 13:13:53

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Помогите создать нужный индекс для запроса

MariaDB совместима c MySQL. То есть, если замените MySQL на MariaDB ничего менять в приложении не нужно (даже клиентские библиотеки).

Неактивен

 

Board footer

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