“SELECT COUNT(column)”是不是比“SELECT COUNT(*)”快/慢? [复制]

Posted

技术标签:

【中文标题】“SELECT COUNT(column)”是不是比“SELECT COUNT(*)”快/慢? [复制]【英文标题】:Is "SELECT COUNT(column)" faster/slower than "SELECT COUNT(*)"? [duplicate]“SELECT COUNT(column)”是否比“SELECT COUNT(*)”快/慢? [复制] 【发布时间】:2011-09-25 07:22:29 【问题描述】:

我在 MSSQL2008 中运行这样的查询:

select count(*)
from t1
inner join t2 on t1.id = t2.t1_id
inner join t3 on t1.id = t3.t1_id 

假设t1.id 有一个NOT NULL 约束。由于它们是内部连接并且t1.id 永远不能为空,因此使用count(t1.id) 而不是count(*) 应该会产生完全相同的最终结果。我的问题是:性能会一样吗?

我也想知道连接是否会影响这一点。我意识到添加或删除连接会影响性能和结果集的长度。假设在不更改连接模式的情况下,您将count 设置为仅针对一个表。会有什么不同吗?也就是说,这两个查询有区别吗:

select count(*)    from t1 inner join t2 on t1.id = t2.t1_id 
select count(t1.*) from t1 inner join t2 on t1.id = t2.t1_id 

COUNT(id) vs. COUNT(*) in mysql 为 MySQL 回答了这个问题,但我找不到专门针对 MS-SQL 的答案,而且我根本找不到任何考虑到join 因素的东西。

注意:我试图在 Google 和 SO 上都找到此信息,但很难弄清楚如何对我的搜索进行措辞。

【问题讨论】:

可能的重复:***.com/questions/1221559/count-vs-count1***.com/questions/2710621/… 【参考方案1】:

我尝试了几个SELECT COUNT(*) FROM MyTableSELECT COUNT(SomeColumn) FROM MyTable 的不同大小的表,其中SomeColumn 曾经是一个聚集键列,一旦它在非聚集索引中,一旦它在没有索引全部。

在所有情况下,对于所有大小的表(从 300,000 行到 1.7 亿行),我在速度和执行计划方面都没有看到任何差异 - 在所有情况下, COUNT 是通过执行聚集索引扫描来处理的——> 即基本上扫描整个表。如果涉及非聚集索引,则扫描在该索引上 - 即使在执行 SELECT COUNT(*)!

在速度或计算这些东西的方法方面似乎没有任何区别 - 要计算它们,SQL Server 只需要扫描整个表 - 期间。

测试是在 SQL Server 2008 R2 开发人员版上完成的

【讨论】:

【参考方案2】:

select count(*) 在尝试获取所有内容时会变慢。指定一个列(PK 或任何其他索引列)将加快速度,因为查询引擎提前知道它在寻找什么。它还将使用索引,而不是针对表格。

【讨论】:

我认为这在很久以前是正确的,但之前关于该主题的讨论表明情况已不再如此。数据库引擎足够聪明,知道 count(*) 应该只检查一行是否存在,而不会获取该行的所有值。 ***.com/questions/1221559/count-vs-count1 @Micheal:我不认为这是普遍正确的。例如,上次我检查时,zOS v9 上的 DB2 仍然获取所有内容。那是很久以前的事了。除非知道他正在处理的数据库的确切工作方式,否则我想避免 count(*) 是安全的。 好的,我的立场是正确的 - 这听起来很合理,它不是普遍正确的......但 OP 指定了 SQL Server 2008。

以上是关于“SELECT COUNT(column)”是不是比“SELECT COUNT(*)”快/慢? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

“滚动” FFT 是不是可能,是不是有用?

GetKeyState() 是不是检测到密钥是不是被释放?

JS判断是不是为数字,是不是为整数,是不是为浮点数

inno setup是不是判断文件是不是存在,然后弹出提示安装时是不是覆盖文件,根据提示安装程序?

除了代码之外,是不是可以检查位置是不是已启用?

如何检查 iframe 是不是已加载或是不是有内容?