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

ACP*_*ACP 18 sql-server-2005 count

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

SELECT COUNT(*) FROM Table
Run Code Online (Sandbox Code Playgroud)

SELECT COUNT(TableId) FROM Table
Run Code Online (Sandbox Code Playgroud)

另外,在性能和执行时间方面有什么不同吗?

Aar*_*and 19

蒂洛钉的区别恰恰...... 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);
Run Code Online (Sandbox Code Playgroud)

(这SUM是为了解释分区表 - 如果您不使用表分区,则可以将其保留.)

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

  • 优化器知道它何时遇到没有WHERE子句的COUNT(*),它应该在最窄的非过滤索引之后,这有希望是PK. (5认同)
  • 在这种情况下,COUNT(PK)和COUNT(*)将是相同的.每个都会给出一个准确的计数,但仍然可以是一个阻止者,仍然可以被阻止.那么这个潜在的性能杀手是否值得准确取决于你(请记住,如果你通过使用NOLOCK"解决"这个问题,你无论如何都会失去准确性). (2认同)

Thi*_*ilo 13

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