8

Count(*) против Count(1) в SQL Server

7

Заголовок: Разница в производительности между Count(1) и Count(*) в SQL Server 2005

Описание проблемы: Здравствуйте! У меня возник вопрос о использовании Count(1) по сравнению с Count(*) в контексте SQL Server 2005. Использует ли кто-нибудь из вас Count(1) вместо Count(*) и есть ли заметная разница в производительности между этими двумя подходами? Или это всего лишь устаревшая практика, которая осталась с прошлых времён? Буду благодарен за любые советы и опыт!

5 ответ(ов)

0

В 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(*)).

Это демонстрирует, как может значительно варьироваться производительность запросов в зависимости от того, как они структурированы.

0

Очевидно, что COUNT(*) и COUNT(1) всегда будут возвращать одинаковый результат. Поэтому, если одна из этих операций будет медленнее другой, это, по сути, будет свидетельствовать о наличии бага в оптимизаторе. Поскольку обе формы используются очень часто в запросах, не имеет смысла, чтобы СУБД допускала существование такого бага без исправления. Таким образом, можно предположить, что производительность обеих форм (вероятно) идентична во всех основных СУБД SQL.

0

В стандарте SQL-92 COUNT(*) конкретно означает "кардинальность выражения таблицы" (это может быть базовая таблица, представление, производная таблица, CTE и т.д.).

Я думаю, основная идея здесь заключается в том, что COUNT(*) легко обрабатывается парсером. Использование любого другого выражения требует от парсера проверки, чтобы оно не ссылалось на какие-либо колонки (например, COUNT('a'), где 'a' — это литерал, и COUNT(a), где 'a' — это колонка, могут давать разные результаты).

В том же духе COUNT(*) легко распознается разработчиком, знакомым со стандартами SQL, что является полезным навыком при работе с несколькими системами управления базами данных (СУБД).

Кроме того, в специальном случае SELECT COUNT(*) FROM MyPersistedTable; предполагается, что СУБД вероятно будет хранить статистику по кардинальности таблицы.

Таким образом, поскольку COUNT(1) и COUNT(*) семантически эквивалентны, я предпочитаю использовать COUNT(*).

0

COUNT(*) и COUNT(1) дают один и тот же результат и имеют одинаковую производительность. Оба этих выражения подсчитывают количество строк в результате запроса.

Тем не менее, COUNT(*) считается более предпочтительным, поскольку он явно указывает на то, что мы хотим подсчитать все строки, независимо от значений в столбцах. В некоторых СУБД COUNT(1) может восприниматься как подсчет значений, равных 1, но фактически это не ухудшает производительность.

В большинстве случаев использование COUNT(*) будет являться стандартом, и предпочтительнее с точки зрения читабельности и ясности кода.

0

В общем, я бы ожидал, что оптимизатор гарантирует отсутствие реальной разницы за исключением каких-то странных крайних случаев.

Как и в случае с любым другим, единственный способ понять — это измерить производительность в ваших конкретных случаях.

Тем не менее, я всегда использовал COUNT(*).

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь