Подтвердить что ты не робот

Count (*) vs Count (Id) в sql server 2005

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

SELECT COUNT(*) FROM Table

и

SELECT COUNT(TableId) FROM Table

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

4b9b3361

Ответ 1

Thilo точно определил разницу... 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).

Ответ 2

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