Почему 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 * я так и не выяснил. Но это и не важно если запрос работает пару микросекунд.

→ Ссылка