前言
记得很早以前就有人跟我说过,在使用count的时候要用count(1)而不要用count(*),因为使用count(*)的时候会对所有的列进行扫描,相比而言count(1)不用扫描所有列,所以count(1)要快一些。当时是对这一结论深信不疑,虽然不知道为什么。今天正好有时间研究研究看count(*)和count(1)到底有没有性能差异。
我的测试环境是SQL Server 2005 SP2开发版。
在进行测试之前先建立一些测试的数据,代码如下:
create table test(a int, b varchar(100))
go
declare @n int
set @n = 1
while @n < 100000
begin
if @n%3 = 0
insert into test values (@n, null)
if @n%3 = 1
insert into test values (@n, str(@n))
if @n%3 = 2
insert into test values (@n, ‘this is text’)
set @n = @n+1
end
这里先说明一下,为了测试的目的,test表里面是故意没有加索引的。
count(*)与count(1)的对比
现在我们开始验证count(*)和count(1)的区别,验证方法很简单,如果两个语句执行效率不一样的话它们的查询计划肯定会不一样的,我们先执行set showplan_text on打开SQL执行计划显示,然后我们执行相应的SQL语句。
先是count(*):
select count(*) from test
/*—————————————————————————
====== 下面是执行计划 ======
|–Compute Scalar(DEFINE:([Expr1004]=CONVERT_IMPLICIT(int,[Expr1005],0)))
|–Stream Aggregate(DEFINE:([Expr1005]=Count(*)))
|–Table Scan(OBJECT:([AdventureWorks].[dbo].[test]))
————————————————————————–*/
接着count(1):
select count(1) from test
/*—————————————————————————
====== 下面是执行计划 ======
|–Compute Scalar(DEFINE:([Expr1004]=CONVERT_IMPLICIT(int,[Expr1005],0)))
|–Stream Aggregate(DEFINE:([Expr1005]=Count(*)))
|–Table Scan(OBJECT:([AdventureWorks].[dbo].[test]))
————————————————————————–*/
对比下两个执行计划我们可以发现是完全一样的,这也就说明count(*)和count(1)的执行效率是完全一样的,根本不存在所谓的单列扫描和多列扫描的问题。
count(col)与count(*)的对比
同样,我们先看一下两个不同count方式的执行计划。
count(*)的执行计划看上面的例子。
count(b)的执行计划:
select count(b) from test
/*—————————————————————————
====== 下面是执行计划 ======
|–Compute Scalar(DEFINE:([Expr1004]=CONVERT_IMPLICIT(int,[Expr1005],0)))
|–Stream Aggregate(DEFINE:([Expr1005]=COUNT([AdventureWorks].[dbo].[test].)))
|–Table Scan(OBJECT:([AdventureWorks].[dbo].[test]))
————————————————————————–*/
现在能看到这两个执行计划唯一不同的地方就是COUNT的内容,对于count(*)是”|—Stream Aggregate(DEFINE:([Expr1005]=count(*)))”,对于count(b)是”|—Stream Aggregate(DEFINE:([Expr1005]=COUNT([AdventureWorks].[dbo].[test].)))”,那这两种count方式会不会有什么不一样呢?
让我们先看一下BOL里面对count(*)以及count(col)的说明:
COUNT(*) 返回组中的项数。包括 NULL 值和重复项。
COUNT(ALL expression) 对组中的每一行都计算 expression 并返回非空值的数量。