我使用SQL COUNT
函数来获取表中的总行数。下面这两个陈述有什么不同吗?
SELECT COUNT(*) FROM Table
和
SELECT COUNT(TableId) FROM Table
另外,在性能和执行时间方面有什么不同吗?
发布于 2010-02-08 06:27:50
Thilo准确地指出了差异..。如果COUNT( * )
可以为NULL
,则column_name
可以返回比NULL
更小的数字。
但是,如果我可以从一个稍微不同的角度来回答您的问题,因为您似乎关注的是性能。
首先,请注意,发出RCSI可能会阻止编写器,而且它也会被其他读取器/编写器阻止,除非您已经更改了隔离级别(下意识地倾向于WITH (NOLOCK)
,但我看到有希望的人最终开始相信SELECT COUNT(*) FROM table;
)。这意味着,当您读取数据以获取“准确”计数时,所有这些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)
。
发布于 2010-02-08 05:56:42
count(id)需要对列进行null检查(对于主键或非null列,可能会对其进行优化),因此最好使用count(*)或count(1) (除非您确实想知道id值为非NULL值的行数)。
https://stackoverflow.com/questions/2219843
复制