Я реализовал этот запрос:
SELECT
evt.userId, evt.storeId, COUNT(1) AS totalVisits
FROM
Event evt
WHERE
evt.timestamp BETWEEN DATE_SUB(NOW(), INTERVAL 30 DAY) AND NOW()
AND
evt.subtype = 2
AND
userID IS NOT NULL
GROUP BY userId, storeId
HAVING totalVisits>16;
Таблица событий содержит миллионы записей.Временная метка столбца - DATETIME, а остальные столбцы - INT.Эта таблица принимается очень часто и имеет много индексов.
В начале выполнение этого запроса занимало более 10 минут.Я решаю эту проблему, добавляя новый индекс
ALTER TABLE Event
ADD INDEX `Event_timestamp_subtype_userId_storeId` (`timestamp` ASC, `subType` ASC, `userId` ASC, `storeId` ASC);
. Это прекрасно работает, и у меня есть результаты менее чем за 2 секунды.
Проблема, с которой я сталкиваюсь, заключается в изменении условия INTERVAL 30 DAY.Если я установлю INTERVAL 50 DAY (например), MYSQL не будет использовать индекс, который я создал.Вместо этого он использует другой индекс, который охватывает только два столбца.
Команда объяснения:
EXPLAIN EXTENDED SELECT
evt.userId, evt.storeId, COUNT(1) AS totalVisits
FROM
Event evt
WHERE
evt.timestamp BETWEEN DATE_SUB(NOW(), INTERVAL 50 DAY) AND NOW()
AND
evt.subtype = 2
AND
evt.userID IS NOT NULL
GROUP BY userId, storeId
HAVING totalVisits>16;
Объяснение ВЫХОД:
+----+-------------+-------+------------+------+------------------------------------------------------------------------------------------------------------+-----------------------------+---------+-------+---------+----------+---------------------------------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+------------------------------------------------------------------------------------------------------------+-----------------------------+---------+-------+---------+----------+---------------------------------------------------------------------+
| 1 | SIMPLE | evt | NULL | ref | Event_userId_index,Event_subType_storeId_index,Event_timetamp_index,Event_timestamp_subtype_userId_storeId | Event_subType_storeId_index | 3 | const | 7375964 | 25.00 | Using index condition; Using where; Using temporary; Using filesort |
+----+-------------+-------+------------+------+------------------------------------------------------------------------------------------------------------+-----------------------------+---------+-------+---------+----------+---------------------------------------------------------------------+
Итак, если поставить 50дни условие запрос является неизменным.Как я могу заставить этот запрос работать с правильными индексами независимо от значения параметров?
Я использую сервер mysql 5.7.23
Спасибо!
С уважением