Count(*) против Count(1) в SQL Server
Заголовок: Разница в производительности между Count(1) и Count(*) в SQL Server 2005
Описание проблемы:
Здравствуйте! У меня возник вопрос о использовании Count(1) по сравнению с Count(*) в контексте SQL Server 2005. Использует ли кто-нибудь из вас Count(1) вместо Count(*) и есть ли заметная разница в производительности между этими двумя подходами? Или это всего лишь устаревшая практика, которая осталась с прошлых времён? Буду благодарен за любые советы и опыт!
5 ответ(ов)
В SQL Server эти операторов выдают одинаковые планы выполнения.
Напротив широко распространенному мнению, в Oracle они тоже.
Функция SYS_GUID() в Oracle является довольно затратной по вычислениям.
В моей тестовой базе данных t_even содержит 1,000,000 строк.
Этот запрос:
SELECT COUNT(SYS_GUID())
FROM t_even
выполняется за 48 секунд, поскольку функция должна будет оценить каждое возвращаемое значение SYS_GUID(), чтобы убедиться, что оно не равно NULL.
Тем не менее, этот запрос:
SELECT COUNT(*)
FROM (
SELECT SYS_GUID()
FROM t_even
)
выполняется всего за 2 секунды, так как он даже не пытается оценить SYS_GUID() (несмотря на то, что * является аргументом для COUNT(*)).
Это демонстрирует, как может значительно варьироваться производительность запросов в зависимости от того, как они структурированы.
Очевидно, что COUNT(*) и COUNT(1) всегда будут возвращать одинаковый результат. Поэтому, если одна из этих операций будет медленнее другой, это, по сути, будет свидетельствовать о наличии бага в оптимизаторе. Поскольку обе формы используются очень часто в запросах, не имеет смысла, чтобы СУБД допускала существование такого бага без исправления. Таким образом, можно предположить, что производительность обеих форм (вероятно) идентична во всех основных СУБД SQL.
В стандарте SQL-92 COUNT(*) конкретно означает "кардинальность выражения таблицы" (это может быть базовая таблица, представление, производная таблица, CTE и т.д.).
Я думаю, основная идея здесь заключается в том, что COUNT(*) легко обрабатывается парсером. Использование любого другого выражения требует от парсера проверки, чтобы оно не ссылалось на какие-либо колонки (например, COUNT('a'), где 'a' — это литерал, и COUNT(a), где 'a' — это колонка, могут давать разные результаты).
В том же духе COUNT(*) легко распознается разработчиком, знакомым со стандартами SQL, что является полезным навыком при работе с несколькими системами управления базами данных (СУБД).
Кроме того, в специальном случае SELECT COUNT(*) FROM MyPersistedTable; предполагается, что СУБД вероятно будет хранить статистику по кардинальности таблицы.
Таким образом, поскольку COUNT(1) и COUNT(*) семантически эквивалентны, я предпочитаю использовать COUNT(*).
COUNT(*) и COUNT(1) дают один и тот же результат и имеют одинаковую производительность. Оба этих выражения подсчитывают количество строк в результате запроса.
Тем не менее, COUNT(*) считается более предпочтительным, поскольку он явно указывает на то, что мы хотим подсчитать все строки, независимо от значений в столбцах. В некоторых СУБД COUNT(1) может восприниматься как подсчет значений, равных 1, но фактически это не ухудшает производительность.
В большинстве случаев использование COUNT(*) будет являться стандартом, и предпочтительнее с точки зрения читабельности и ясности кода.
В общем, я бы ожидал, что оптимизатор гарантирует отсутствие реальной разницы за исключением каких-то странных крайних случаев.
Как и в случае с любым другим, единственный способ понять — это измерить производительность в ваших конкретных случаях.
Тем не менее, я всегда использовал COUNT(*).
Какой самый эффективный способ страницировать результаты в SQL Server?
Обновление данных в одной таблице из другой на основе совпадения ID
Как вставить перенос строки в строке VARCHAR/NVARCHAR SQL Server
Возможно ли задать условия в Count()?
with(nolock) или (nolock) - есть ли разница?