Простой SQL запрос, но огромная таблица - как оптимизировать? - PullRequest
1 голос
/ 16 апреля 2020

У меня очень простой запрос MySQL:

SELECT target FROM table WHERE goal_id=1 AND year>=2015 AND year<=2020

В таблице около 5 миллионов строк. И как результат, он очень медленный (около 10 секунд).

Что я могу сделать, чтобы улучшить ситуацию? Поможет ли индекс, и если да, то по какому столбцу?

Ответы [ 4 ]

3 голосов
/ 16 апреля 2020

Для этого запроса вам нужен следующий индекс:

create index myindex on mytable(year, goal_id, target)

Это дает вам охватывающий индекс : все столбцы, которые вступают в игру в запросе, являются частью индекса, так что это дает базе данных хорошую возможность выполнить запрос, просматривая только индекс (без фактического рассмотрения data ).

Порядок столбцов в индексе важен: первые два столбца соответствуют предикатам where, а последний столбец - это столбец, который вступает в игру в предложении select.

В зависимости от мощности ваших данных, вы также можете попробовать инвертировать первые два столбца:

create index myindex on mytable(goal_id, year, target)

Основная идея заключается в том, что вы хотите сначала поставить более строгие критерии.

2 голосов
/ 16 апреля 2020

Индекс year, goal_id и target:

ALTER TABLE table ADD INDEX index_name (goal_id, year, target)

Как указывал Рик Джеймс , goal_id должен быть первым в составной индекс, потому что он соответствует =, за которым следует столбец диапазона year, а затем то, что вы хотите получить, то есть target.

1 голос
/ 17 апреля 2020

Правило простое. Вещи (ы), проверенные с = в первую очередь. Тогда сделайте не более одного «диапазона». (И BETWEEN эквивалентно по производительности эквивалентной паре неравенств.)

Дополнительные обсуждения: http://mysql.rjweb.org/doc.php/index_cookbook_mysql

И, как указывает GMB, расширение индекс, чтобы сделать это покрытие дает еще один импульс. Вся работа выполняется в BTree индекса; Не нужно заглядывать в данные BTree. Итак, в таком порядке :

INDEX(goal_id, year, target)
0 голосов
/ 16 апреля 2020

ВЫБРАТЬ цель ИЗ таблицы, ГДЕ goal_id = 1 И ГОД МЕЖДУ 2015 И 2020 ГОДАМИ

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

...