天天看点

SQL性能调优实践——SELECT COUNT

最近想深入学习sql,在网上搜索到一些sql 优化的资料要么是张冠李戴,oracle 优化的资料硬是弄成啦ms sql 优化的资料,而且被很多人转载,收藏,有些要么有些含糊不清,好像是那么回事,也没经过验证,实践出真知!下面是我对select count(*), select count(1),select count (0), select count(field)等孰优孰劣的测试结果,如果测试方法有什么不足,也希望大家给点建议。

首先我们来看看测试的机器、以及开发环境吧:双核处理器 t6670  2g ddr2的内存 数据版本如下图所示:

SQL性能调优实践——SELECT COUNT

  然后建一个简单的测试表

好,到目前为止我们已经把测试用的表、数据都弄好啦,接下来我们来看看执行一次select count 的使用时间

code snippet

dbcc dropcleanbuffers;

dbcc freeproccache;

set statistics time on;

select count(0) from employee

set statistics time off;

我们会得到下面的输出结果

dbcc 执行完毕。如果dbcc 输出了错误信息,请与系统管理员联系。

sql server 执行时间:

   cpu 时间= 219 毫秒,占用时间= 1033 毫秒。 

接下来我们来看看各种count的实际执行计划,截图如下

SQL性能调优实践——SELECT COUNT
SQL性能调优实践——SELECT COUNT

我很纳闷为什么执行计划都是一样的,希望有高手能解答。

接下来,那么我们把上面的脚本执行10次,把每次得到的数据记录下来,然后我们依次用

依葫芦画瓢每段脚本执行10次,最后我们求得到的结果的平均值,为了形象显示,我用excel把数据显示如下: 

 select count(1) from employee

SQL性能调优实践——SELECT COUNT

select count(0) from employee

SQL性能调优实践——SELECT COUNT

select count(*) from employee

SQL性能调优实践——SELECT COUNT

select count(employeename) from employee

SQL性能调优实践——SELECT COUNT

从实验结果来看,执行快慢的顺序为: count(employeename) > count(0) ~= count(1) > count(*);从实验结果来看,我们至少验证了 count(0) ~= count(1) > count(*)的结论,网上有篇帖子《sql server 索引结构及其使用》篇所下的结论count(*)不比count(字段)慢 显然是不严谨的,他只做了一次实验,而我们这里是10次结果的平均值。那么现在问题来了,为什么count(employeename)要快于count(0) >= count(1),它如果不是主键、字段没有索引呢?网上不是有些资料显示count(1)效率最高,速度最快吗? 我们10次得到平结值有没有误差呢?抽样能否反映事实呢?下面我用这个方法来大量获得语句执行时间,然后求平均值,(我觉得这方法应该是可以反映实际cpu时间的)如果有不妥的地方,也希望大家指正。 创建下面一个表

然后也依次得到其它几种sql 的执行时间,另外我们也把count(department)得数据加入进来,下面是我得到的实验结果的平均值

count(1)

count(0)

count(*)

count(employeename)

count(department)

100.09

99.27

100.28

65.95

134.13

SQL性能调优实践——SELECT COUNT

数据显示也与上面的测试结果相一致,虽然得到了这些结果,由于统计偏差缘故,count(0)比 count(1) 稍稍快些,这个是完全可以忽略,因为我统计的次数比小,很容易造成偏差,count(*) 接

近于count(1),估计是由于数据缓存缘故,其实我们从实验结果可以看出统计数据的速度:

对索引字段统计要快于count(1),原因是count(1)是要走全表扫描,而count(1) 快于count(*)

,是因为count(*)走全表扫描的开销要大于count(1), 至于统计非索引字段count(department),比较偏大的,则让我有点纳闷,估计是统计偏差缘故。