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,1NOT 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 = OFFON [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 *查询要高。如果有哪位高人知道确切的原因请告诉我。
原文地址:https://www.cnblogs.com/zengezenge/p/826235.html