Кажется, что критерии на created_at
очень избирательны (глядя только на последние 7 дней?).Нам не терпится исследовать индекс с created_at
в качестве ведущего столбца.
Запрос также ссылается на столбец product_token
из той же таблицы, поэтому мы можем включить этот столбец в индекс, чтобы сделать егоиндекс покрытия.
api_events_IX ON api_events ( created_at, product_token )
Используя этот индекс, мы, вероятно, можем избежать рассмотрения подавляющего большинства из 31 миллиона строк и быстро сузить подмножество строк, на которые мы действительно должны смотреть.
Используя индекс, для запроса все равно потребуется операция «Использование сортировки файлов», чтобы удовлетворить GROUP BY.
(Я предполагаю, что соединение с 12 строками в продукте не исключаетмного строк ... что в подавляющем большинстве строк в api_event
product_token
относится к строке, существующей в product
.
Используйте MySQL EXPLAIN
, чтобы увидеть запросплан выполнения.
Еще одним возможным уточнением (для проверки производительности) будет выполнение некоторой агрегации во встроенном представлении:
SELECT SUM(s.count_all) AS count_all
, p.name
FROM ( SELECT COUNT(*) AS count_all
, ae.product_token
FROM api_events ae
WHERE ae.created_at > '2019-01-21 12:16:53.853732'
GROUP
BY ae.product_token
) s
JOIN products p
ON p.token = s.product_token
GROUP
BY p.name
Еслипредположение о product_token
дезинформировано, еслиВ api_event
есть много строк, которые имеют product_token
значений, которые не ссылаются на строку в product
... мы могли бы пойти другим путем ...