----------------------------------------------------------------------------
---- 本文为andkylee个人原创,请在尊重作者劳动成果的前提下进行转载;
---- 转载务必注明原始出处 : http://blog.csdn.net/andkylee
---- 关键字: sybase 聚簇索引 非聚簇索引 查询计划 行数 count
----------------------------------------------------------------------------
在sybase表上建立聚集索引可以提高键列的检索速度。这是索引的主要功能所在。
可是,聚集索引对于统计表上的行数count(*)有没有改善呢? 答案是否定的。
请看我下面的测试代码!
建立一张临时表test3
向表中插入测试数据
打开查询计划和统计查询计划时间的选项
表上没有加任何索引的情况下。
select count(*) from test4 的查询计划为:
select count(1) from test4 的查询计划为:
可以看出,count(*) 和count(1) 的执行计划是相同的。都执行了表扫描。
由于表上没有任何索引可供使用,select count(id) 和 select count(name) 都是执行了表扫描。
下面考虑加入主键(聚集索引)pk_test4_id
再次执行select count(*) from test4 和 select count(1) from test4
由上可以看出,聚集索引对于select count(*) 几乎没有扫描影响。堆表和聚集索引表上的count是没有什么区别的,甚至于聚集索引表上的IO还要多2(这是因为多了两个聚集索引的数据块造成的)。其实聚集索引并没有单独的保留所有索引列的信息,而只是将表中的行的物理顺序按照聚集索引列的顺序整理了一下,因此对聚集索 引的扫描和对堆表的扫描是一样的,没有什么本质上的区别。
添加id列上的非聚集索引idx_test4_id
此时再次执行select count(*) 和select count(1)。查询计划如下:
可以看出查询引擎使用了非聚集索引idx_test4_id ,执行时间明显减少。因为计算行数这个操作对于全表扫描或是非聚集索引的扫描结果是一样的,而相对来说非聚集索引的数据量是肯定会比表的数据量小很多的,同样的做一次全部扫描所花费的IO也就要少很多了。
select count(id) 也是利用了非聚集索引 idx_test4_id。
结论:
count(*)和count(1)执行的效率是完全一样的。
如果是对特定的列做count的话建立这个列的非聚集索引能对count有很大的帮助。