昨天看到了GoodSpeed(Blog地址http://goodspeed.cnblogs.com/)发的帖子《SELECT * 的真相: 索引覆盖(index coverage)》(http://www.cnblogs.com/goodspeed/archive/2007/07/20/index_coverage.html)之后我觉得不可思议:查询的字段都是一样的,为什么Select *就会比显示的列出字段名的查询性能差呢,为了验证我决定做一个例子实验一下。
我在数据库中建了一张表,表的创建脚本如下:
使用Select *查询的查询代码如下:
使用Select * 查询耗时时间表:
感觉时间相差有点大,但是我又做了一次测试,时间又基本一样,给人的感觉就是使用Select *查询性能不如显示查询稳定。如果说是表Scan耗时,但是有时候两者的时间又是一样。
我估计是原因是:使用显示查询SQL Server为查询做准备并且准备的执行计划被命中的可能性比使用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条记录,代码如下: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]
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次(为了避免干扰去掉了数据回显)。2 com.Connection = con
3 For i As Integer = 0 To 1000000
4 com.ExecuteNonQuery()
5 Next
使用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
使用显示查询的查询代码如下: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
使用显示字段查询的查询耗时表: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 |
次数 |
时间(毫秒) |
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 |
我估计是原因是:使用显示查询SQL Server为查询做准备并且准备的执行计划被命中的可能性比使用Select *查询要高。如果有哪位高人知道确切的原因请告诉我。