Как MySQL решает, использует ли он индекс для GROUP BY? - PullRequest
4 голосов
/ 08 декабря 2011

У меня есть простая таблица

stock_ledger_id   INT(10) (Primary)
piece_to_bin_id   INT(10)
quantity          INT(11)
create_datetime   TIMESTAMP
... and a few VARCHARs

с некоторыми простыми индексами

Key_name          Cardinality
PRIMARY               1510443
piece_to_bin_id        100696

Этот довольно простой запрос занимает около 8 секунд:

SELECT piece_to_bin_id,
       SUM(quantity),
       MAX(create_datetime)
FROM stock_ledger
GROUP BY piece_to_bin_id

Вот ОБЪЯСНЕНИЕ:

id select_type table        type possible_keys key  key_len ref  rows    Extra                           
1  SIMPLE      stock_ledger ALL  NULL          NULL NULL    NULL 1512976 Using temporary; Using filesort 

Я обнаружил, что Я могу снизить его примерно до 0,5 секунды , форсировав индекс:

SELECT piece_to_bin_id,
       SUM(quantity),
       MAX(create_datetime)
FROM stock_ledger
FORCE INDEX (piece_to_bin_id)
GROUP BY piece_to_bin_id

Тогда ОБЪЯСНЕНИЕ выглядит так:

id select_type table        type  possible_keys key             key_len ref  rows    Extra
1  SIMPLE      stock_ledger index NULL          piece_to_bin_id 4       NULL 1512976

Я использую MySQL 5.1.41, таблица - MyISAM, и раньше я запускал ANALYZE TABLE.

Так что я застрял с "MySQL снова ошибся, просто принудительно индексировать" или есть реальная причина, почему MySQL использует полное сканирование таблицы? Может быть, один я могу исправить?

1 Ответ

1 голос
/ 10 декабря 2011

В любом случае запрос требует полного сканирования таблицы, возможно, mysql пытается избежать дополнительного перехода от значения ключа к строке. Для запроса может быть гораздо больше преимуществ от составного (piece_to_ bin_id, create_datetime) индекса или даже (piece_to_ bin_id, create_datetime, количество). Последний станет индексом покрытия.

UPD

Кажется, в 16 раз быстрее получается результат распределения данных в вашем случае (возможно, множество смежных строк с одинаковым piece_to_bin_id отсортировано по create_datetime). MyISAM, похоже, использует индексы для запросов, которые уменьшают количество результирующих строк, потому что их использование подразумевает случайные операции ввода-вывода на диске.

Я никогда не обращал на это внимания, но мои текущие тесты на таблице из 10К строк показывают, что MyISAM даже не использует индекс для сортировки запроса, например:

SELECT indexed_field, another_field
FROM a_table
ORDER BY indexed_field;

Даже когда indexed_field является первичным ключом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...