SELECT * 的真相: 索引覆盖(index coverage)的实验结果

      昨天看到了GoodSpeed(Blog地址 http://goodspeed.cnblogs.com/)发的帖子《SELECT * 的真相: 索引覆盖(index coverage)》( http://www.cnblogs.com/goodspeed/archive/2007/07/20/index_coverage.html)之后我觉得不可思议:查询的字段都是一样的,为什么Select *就会比显示的列出字段名的查询性能差呢,为了验证我决定做一个例子实验一下。
      我在数据库中建了一张表,表的创建脚本如下:
1  CREATE   TABLE   [ dbo ] . [ Performance ] (
2       [ PK ]   [ int ]   IDENTITY ( 1 , 1 NOT   NULL ,
3       [ Data ]   [ int ]   NOT   NULL ,
4       [ DateTime ]   [ datetime ]   NOT   NULL   CONSTRAINT   [ DF_Performance_DateTime ]    DEFAULT  ( getdate ()),
5    CONSTRAINT   [ PK_Performance ]   PRIMARY   KEY   CLUSTERED  
6  (
7       [ PK ]   ASC
8  ) WITH  (IGNORE_DUP_KEY  =   OFF ON   [ PRIMARY ]
9  ON   [ PRIMARY ]
然后又使用代码插入了1000001条记录,代码如下:
1      Dim  com  As   New  SqlClient.SqlCommand( " Insert Into Performance( Data ) Values( 1 ) " )
2     com.Connection  =  con
3     For  i  As   Integer   =   0   To   1000000
4         com.ExecuteNonQuery()
5     Next
     插入数据代码然后使用如下的查询命令分别进行查询10次(为了避免干扰去掉了数据回显)。
     使用Select *查询的查询代码如下:
1     Dim  com  As   New  SqlClient.SqlCommand( " Select * From Performance " )
2    com.Connection  =  con
3    Dim  reader  As  SqlDataReader  =  com.ExecuteReader(CommandBehavior.CloseConnection)
4 
5    Dim  time  As  DateTime  =  DateTime.Now
6    While  reader.Read
7    End   While
     使用显示查询的查询代码如下:
1     Dim  com  As   New  SqlClient.SqlCommand( " Select PK, Data, DateTime From Performance " )
2    com.Connection  =  con
3    Dim  reader  As  SqlDataReader  =  com.ExecuteReader(CommandBehavior.CloseConnection)
4 
5    Dim  time  As  DateTime  =  DateTime.Now
6    While  reader.Read
7    End   While
     使用显示字段查询的查询耗时表:
次数
时间(毫秒)
1
468.756
2
468.756
3
484.3812
4
484.3812
5
484.3812
6
484.3812
7
484.3812
8
484.3812
9
484.3812
10
484.3812
      使用Select * 查询耗时时间表:
次数
时间(毫秒)
1
500.0064
2
484.3812
3
484.3812
4
484.3812
5
734.3844
6
750.0096
7
750.0096
8
734.3844
9
765.6348
10
750.0096
      感觉时间相差有点大,但是我又做了一次测试,时间又基本一样,给人的感觉就是使用Select *查询性能不如显示查询稳定。如果说是表Scan耗时,但是有时候两者的时间又是一样。
      我估计是原因是:使用显示查询SQL Server为查询做准备并且准备的执行计划被命中的可能性比使用Select *查询要高。如果有哪位高人知道确切的原因请告诉我。

你可能感兴趣的:(select)