Количество (*) по сравнению с количеством (Айдахо) в SQL-сервере 2005

Я использую SQL COUNT функция для получения общего количества или строк от таблицы. Есть ли какое-либо различие между этими двумя следующими утверждениями?

SELECT COUNT(*) FROM Table

и

SELECT COUNT(TableId) FROM Table

Кроме того, есть ли какое-либо различие в терминах производительности и время выполнения?

18
задан mauris 5 May 2011 в 03:36
поделиться

2 ответа

Тило точно определил разницу ... COUNT (имя_столбца) может возвращать меньшее число, чем COUNT (*) if имя_столбца может иметь значение NULL .

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

Во-первых, обратите внимание, что выдача SELECT COUNT (*) FROM table; потенциально заблокирует писателей, а также будет заблокирована другими читателями / писателями, если вы не изменили уровень изоляции (как правило, быть С (NOLOCK) , но я вижу многообещающее количество людей, наконец, начинающих верить в RCSI). Это означает, что пока вы читаете данные, чтобы получить «точный» счетчик, все эти запросы DML накапливаются, и когда вы, наконец, снимаете все свои блокировки, шлюзы открываются, куча вставок / обновлений / удаления активность происходит, и идет ваш «точный» подсчет.

Если вам нужен абсолютно согласованный и точный с точки зрения транзакций счетчик строк (даже если он действителен только для количества миллисекунд, которое требуется для возврата вам числа), тогда SELECT COUNT (*) - ваш единственный выбор.

С другой стороны, если вы пытаетесь получить приблизительную точность на 99,9%, вам будет гораздо лучше выполнить такой запрос:

SELECT row_count = SUM(row_count)
  FROM sys.dm_db_partition_stats
  WHERE [object_id] = OBJECT_ID('dbo.Table')
  AND index_id IN (0,1);

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

Это DMV поддерживает точное количество строк для таблиц, за исключением строк, которые в настоящее время участвуют в транзакциях - и именно эти транзакции заставят ваш запрос SELECT COUNT ждать (и в конечном итоге заставить его неточно, прежде чем вы успеете его прочитать). Но в противном случае это приведет к гораздо более быстрому ответу, чем предложенный вами запрос, и не менее точному, чем использование WITH (NOLOCK) .

19
ответ дан 30 November 2019 в 07:49
поделиться

count(id) требует проверки столбца на null (что может быть оптимизировано для первичного ключа или другого не нулевого столбца), поэтому лучше использовать count(*) или count(1) (если только вы действительно не хотите узнать количество строк с не нулевым значением для id).

13
ответ дан 30 November 2019 в 07:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: