Количество (*) против количества (Id) в SQL Server 2005 - PullRequest
18 голосов
/ 08 февраля 2010

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

SELECT COUNT(*) FROM Table

и

SELECT COUNT(TableId) FROM Table

Кроме того, есть ли разница в производительности и времени выполнения?

Ответы [ 2 ]

19 голосов
/ 08 февраля 2010

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

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

Во-первых, обратите внимание, что выдача SELECT COUNT(*) FROM table; потенциально заблокирует писателей, а также будет заблокирована другими читателями / писателями, если вы не изменили уровень изоляции (коленный рывок обычно равен WITH (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).

13 голосов
/ 08 февраля 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...