我在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上找到这些信息,但很难弄清楚如何说出我的搜索结果。
答案 0 :(得分:11)
我尝试了一些具有各种大小的表的SELECT COUNT(*) FROM MyTable
与SELECT COUNT(SomeColumn) FROM MyTable
,并且SomeColumn
曾经是一个群集键列,一旦它在非聚集索引中,并且一旦它完全没有索引。
在所有情况下,对于所有尺寸的表格(从300,000行到1.7亿行),我从未在速度和执行计划方面看到任何差异 - 在所有情况下,通过进行聚簇索引扫描来处理COUNT
- >即基本上扫描整个表格。如果涉及非聚集索引,则扫描在该索引上 - 即使在执行SELECT COUNT(*)
时也是如此!
在速度或方法方面似乎没有任何差别如何计算 - 计算全部,SQL Server只需扫描整个表 - 期间。
在SQL Server 2008 R2 Developer Edition上进行了测试
答案 1 :(得分:-1)
select count(*)
在尝试获取所有内容时会变慢。指定列(PK或任何其他索引列)将加速事情,因为查询引擎提前知道它正在寻找什么。它也会使用一个索引而不是反对该表。