Какой оператор в SQL подсчитывает количество строк в таблице
QA инженерSQLбазы данныхзапросы SQLподсчет строк
Что проверяют
Знаете ли вы разницу между тремя формами подсчёта и понимаете ли, что это не бесплатная операция.
Как отвечать
Функция агрегации подсчёта. Три формы, и различие между ними принципиальное:
- *`count()` считает все строки**, попавшие в выборку, независимо от значений;
count(колонка)считает строки, где значение колонки не пустое. Пустые пропускаются;count(distinct колонка)считает уникальные непустые значения.
select count(*) from users; -- всего строк
select count(phone) from users; -- у скольких заполнен телефон
select count(distinct city) from users; -- сколько разных городовРазница между первыми двумя это классический источник расхождений в отчётах: цифры не сходятся именно потому, что где-то посчитали колонку с пустыми значениями.
Что важно знать про производительность, потому что вопрос часто продолжают:
- в PostgreSQL подсчёт всех строк требует прохода по таблице. Готового счётчика в метаданных нет, и причина в механизме версионности: разные транзакции видят разное число строк, поэтому единственно верного числа просто не существует. На таблице в десятки миллионов строк это секунды;
- когда точность не нужна, берут приблизительную оценку из системной статистики. Для показа «примерно столько результатов» этого достаточно;
- при соединении таблиц подсчёт считает строки результата, а не исходной таблицы. Соединение «один ко многим» легко даёт число больше ожидаемого, и это частая ошибка в отчётах;
- условие фильтрации может быть встроено прямо в агрегат, что позволяет за один проход посчитать и общее число, и число подходящих под условие.
Где спотыкаются
Считают колонку вместо всех строк и получают заниженное число.
Ждут, что подсчёт выполнится мгновенно на большой таблице.
Не замечают размножения строк при соединении.
Не знают про приблизительную оценку и грузят базу точным подсчётом ради счётчика на странице.