2011-02-17

Не все индексы одинаково полезны

Имеется InnoDB табличка, небольшая - меньше миллиона записей, делаем такой запрос (нужно получить top10 доменов):
> select dlvDestinationDomain, count(*) from email_accounting where jobid="11837" group by dlvDestinationDomain order by count(*) desc limit 10

созданы следующие индексы:

PRIMARY BTREE id
jobId BTREE jobId
dlvDestinationDomain BTREE dlvDestinationDomain
dlvDestinationDomain_2 BTREE dlvDestinationDomain
A
jobId_3 BTREE jobId
A

Обнаружилась забавная вещь: некоторые индексы не только не ускоряют но и замедляют агрегатные запросы:

вообще без использования индексов:

mysql> select dlvDestinationDomain, count(*) from email_accounting IGNORE INDEX(dlvDestinationDomain_2, jobId_3, jobId, dlvDestinationDomain) where jobid="11837" group by dlvDestinationDomain order by count(*) desc limit 10;

3.09 секунды

используя индекс по jobId дает небольшой прирост производительности:

mysql> select dlvDestinationDomain, count(*) from email_accounting FORCE INDEX (jobId) where jobid="11837" group by dlvDestinationDomain order by count(*) desc limit 10;

2.13 секунд;

использование составного индекса по jobID и dlvDestinationDomain сделало все гораздо веселее:

mysql> select dlvDestinationDomain, count(*) from email_accounting FORCE INDEX (jobId_3) where jobid="11837" group by dlvDestinationDomain order by count(*) desc limit 10;

0.39 секунд;

ипользование ключа с полям в обратном порядке  (dlvDestinationDomain и jobID) работает гораздо хуже:

mysql> select dlvDestinationDomain, count(*) from email_accounting FORCE INDEX (dlvDestinationDomain_2) where jobid="11837" group by dlvDestinationDomain order by count(*) desc limit 10;

1.36 секунд;

А вот использование ключа только по dlvDestinationDomain заставляет MySQL думать почти две минуты:

mysql> select dlvDestinationDomain, count(*) from email_accounting FORCE INDEX (dlvDestinationDomain) where jobid="11837" group by dlvDestinationDomain order by count(*) desc limit 10;

1 минута 48 секунд;

Кстати, заметил, что использование jobid="11837" (jobid у меня текстовое) заметно прибавляет скорости против jobid=11837. Не зря в strict моде MySQL грязно ругается на такие преобразования, ох не зря...

Upd. Во всем оказались замешаны настройки InnoDB, если увеличить в my.cnf значение переменной innodb_buffer_pool_size то скорость выполнения агрегативного запроса с индексом по группируемому полю заметно возрастает и картина меняется на прямо противоположную.

 

комментарии:

 

Для того чтобы каждый раз не представляться можно войти как зарегистрированный пользователь.

Имя*

разрешены только теги br, font, span, p, strong, u, p, blockquote, a, div, img - остальные будут безжалостно удаляться