Тило разбра точно разликата... 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)
.