Почему SELECT COUNT(*) выполняется дольше SELECT *?
Есть такой запрос
SELECT COUNT(*)
FROM `t`
WHERE `date` BETWEEN '2020-05-19' AND '2020-05-20'
AND `ref_id` IS NOT NULL
AND `field` = 0
Есть составной индекс ref_id, field, date.
В результате запроса мы получаем число около 30-40, для периода в 1 день.
Запрос выполняется за 0.2 секунды, не смотря на то, что индекс покрывающий.
EXPLAIN показывает, что индекс используется, что SELECT_TYPE: SIMPLE, TYPE: range, EXTRA: Using where; Using index
Но несмотря на, вроде бы, подходящий индекс запрос выполняется сравнительно долго, учитывая, что он выполняется сотни тысяч раз в день.
Если в запросе просто убрать COUNT и оставить SELECT *, то время выполнения будет 0.09 секунд, в 2 раза быстрее.
И вот вопрос почему запрос с COUNT выполняется в 2 раза дольше? Ведь если мы используем COUNT, то запрос использует только данные из индекса, это видно в EXPLAIN EXTRA: Using where; Using index. А когда мы используем просто SELECT *, то EXTRA: Using index condition
И в конце концов как ускорить этот запрос?
Ответы (1 шт):
Спасибо @t0lik за наводку. Дело в том, что составной индекс сослужит плохую службу. Для ускорения запроса было достаточно создать индекс date, так как его селективность наилучшая и её достаточно для выполнения запроса.
Но почему COUNT(*) выполнялся дольше чем SELECT * я так и не выяснил. Но это и не важно если запрос работает пару микросекунд.