Как правило, стоимость COUNT(*)
стоимости пропорциональна количеству записей, удовлетворяющих условиям запроса, плюс времени, необходимому для подготовки этих записей (зависит от сложности базового запроса).
В простых случаях, когда вы имеете дело с одной таблицей, часто существуют специальные оптимизации, чтобы сделать такую операцию дешевой. Например, выполнение COUNT(*)
без WHERE
условий из одной таблицы MyISAM
в MySQL
- это происходит мгновенно, так как хранится в метаданных.
Например, давайте рассмотрим два запроса:
SELECT COUNT(*)
FROM largeTableA a
Поскольку каждая запись удовлетворяет запросу, стоимость COUNT(*)
пропорциональна количеству записей в таблице (т. Е. Пропорциональна тому, что она возвращает) (при условии, что ей нужно посетить строки, и на месте нет определенной оптимизации справиться с этим)
SELECT COUNT(*)
FROM largeTableA a
JOIN largeTableB b
ON a.id = b.id
В этом случае движок, скорее всего, будет использовать HASH JOIN
, и план выполнения будет выглядеть примерно так:
- Построить хеш-таблицу на меньшем из столов
- Сканирование таблицы большего размера, поиск каждой записи в хэш-таблице
- Считайте спички по ходу.
В этом случае издержки COUNT(*)
(шаг 3) будут незначительными, и время запроса будет полностью определено шагами 1 и 2, то есть построением хеш-таблицы и ее поиском. Для такого запроса время будет O(a + b)
: оно не зависит от количества совпадений.
Однако, если есть индексы как a.id
, так и b.id
, можно выбрать MERGE JOIN
, а время COUNT(*)
будет пропорционально количеству совпадений, поскольку поиск по индексу будет выполнен после каждый матч.