MySQL Query Optimization Group By с Максом - PullRequest
0 голосов
/ 26 марта 2019

Попытка оптимизировать MySQL-запрос, который использует Group by с Max. Попытка получить последние обновленные кадры, которые были активны до какой-либо прошлой даты.

Структура таблицы кадров аудита:

id bigint pk AI
frame_id bigint fk
name VARCHAR(50)
active int
createdOn DATETIME
updatedOn DATETIME
deletedOn DATETIME

id, frame_id и updatedOn имеют индивидуальные индексы ..

Текущий запрос:

SELECT MAX(id) as id1 
  FROM audit_frame_master 
 WHERE updatedOn <='2019-03-25 21:00:00' 
   AND active=1 
   AND deletedOn IS NULL 
 GROUP 
    BY frame_id

Производительность:

Таблица имеет около 1М строк. Это занимает в среднем 4 секунды. Есть ли способ оптимизировать запрос выше?

Ниже приведено выражение EXPLAIN для того же. enter image description here

Ответы [ 2 ]

1 голос
/ 26 марта 2019

Запрос выглядит нормально. Все, что вы можете сделать, это предоставить соответствующий индекс. Это будет индекс по столбцам в предложении WHERE как минимум. Начните с самого ограничительного столбца. Таким образом,

  • сколько строк соответствует active = 1?
  • сколько строк соответствует deletedOn IS NULL?
  • сколько строк соответствует updatedOn <= timestamp '2019-03-25 21:00:00'?

Выберите тот, который получает наименьшее количество строк. Скажите, что это active, затем updatedOn, затем deletedOn. Это дает вам:

create index idx on audit_frame_master(active, updatedOn, deletedOn);

Поскольку вы хотите сгруппировать по frame_id, а затем найти максимум id, вы можете добавить их в следующем порядке:

create index idx on audit_frame_master(active, updatedOn, deletedOn, frame_id, id);

Это индекс покрытия. Если СУБД использует его, ей даже не нужно обращаться к таблице.

СУБД может использовать или не использовать этот индекс. Это просто предложение. Если СУБД считает, что будет слишком много работы для просмотра индекса, а не просто для последовательного чтения таблицы, она не будет ее использовать. Просто попробуй.

0 голосов
/ 26 марта 2019

Добавьте следующий составной индекс: (frame_id, active, deletedOn, updatedOn, id) и сообщите, как он работает.

...