在sql server 2005中计数(*)vs Count(Id)

时间:2010-02-08 05:54:37

标签: sql-server-2005 count

我使用SQL COUNT函数从表中获取总数或行数。以下两个陈述之间有什么区别吗?

SELECT COUNT(*) FROM Table

SELECT COUNT(TableId) FROM Table

此外,在性能和执行时间方面是否存在差异?

2 个答案:

答案 0 :(得分:19)

Thilo准确地确定了差异......如果COUNT( column_name )可以是COUNT( * ),则column_name可以返回低于NULL的数字。

然而,如果我在回答你的问题时可以采取略微不同的角度,因为你似乎专注于表现。

首先请注意,发布SELECT COUNT(*) FROM table;可能会阻止编写者,除非您更改了隔离级别,否则它也会被其他读者/编写者阻止(但是我只能WITH (NOLOCK)但我是SELECT COUNT( * )我看到有很多人终于开始相信RCSI了。这意味着当您正在读取数据以获得“准确”计数时,所有这些DML请求都堆积起来,当您最终释放所有锁时,闸门打开,一堆插入/更新/删除活动发生了,你的“准确”计数。

如果您需要绝对事务一致且准确的行数(即使它只对您返回数字所需的毫秒数有效),那么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); 是您唯一的选择。

另一方面,如果你想要获得99.9%的准确率,你可以通过这样的查询获得更好的效果:

SUM

SELECT COUNT用于解释分区表 - 如果您不使用表分区,则可以将其删除。)

此DMV维护表的准确行数,但当前正在参与事务的行除外 - 这些事务将使您的WITH (NOLOCK)查询等待(并最终使其在您拥有之前不准确)时间阅读它)。但除此之外,这将导致比您提出的查询更快的答案,并且不比使用{{1}}更准确。

答案 1 :(得分:13)

count(id)需要对列进行空值检查(可以针对主键或其他非空列进行优化),因此应优先考虑count(*)或count(1)(除非你真的想要知道id为非空值的行数。