我使用SQL COUNT
函数从表中获取总数或行数。以下两个陈述之间有什么区别吗?
SELECT COUNT(*) FROM Table
和
SELECT COUNT(TableId) FROM Table
此外,在性能和执行时间方面是否存在差异?
答案 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为非空值的行数。