Select语句的性能比对

一、问题

网上流传着各种sql选择语句优化技巧,其中就包括选择sql语句构造,包括以下几种情况:

1. select * from 表名

2. select [字段名] from 表名

3. select [数据库名].[架构名].[表名].[字段名] from 表名


表名又分为:

4.[数据库名].[架构名].[表名]

5.[架构名].[表名]

6.[表名]

网上认为2,3性能肯定好于1的性能,为了验证这个观点,本文进行了验证.以下是各种sql语句的测试情况

二、问题验证

declare @i int,@max int ,@UID int,@StartTime datetime ,@EndTime datetime,@sql varchar(3000),@tableName varchar(100)
declare @span1 varchar(30),@span2 varchar(30),@span3 varchar(30)

select @max = 100 ,@UID = 45000307 --最大测试次数 , 用户ID

select @tableName = '[TestDB].[dbo].[C_Contacts]'
select @tableName = '[dbo].[C_Contacts]'
select @tableName = '[C_Contacts]'

--测试select *
set @i=0
set @sql = 'select * from ' + @tableName + ' where UMID ='+Convert(varchar(30),@UID)
set @StartTime = GETDATE();
while(@i<@max)
begin
execute(@sql)
set @i = @i+1
end
set @EndTime = GETDATE();
set @span1 = convert(varchar(30),DATEDIFF(MS,@StartTime,@EndTime))


--测试select [字段名]
set @i=0
set @sql = 'select [ContactID],[UMID],[FirstName],[LastName],[Birthday],[Photo],[Remarks],[Ver],[InsTime],[UpdTime] from ' + @tableName + ' where UMID ='+Convert(varchar(30),@UID)
set @StartTime = GETDATE();
while(@i<@max)
begin
execute(@sql)
set @i = @i+1
end
set @EndTime = GETDATE();
set @span2 = convert(varchar(30),DATEDIFF(MS,@StartTime,@EndTime))


--测试select [数据库名].[架构名].[表名].[字段名]
set @i=0
set @sql = 'select [dbo].[C_Contacts].[ContactID],[dbo].[C_Contacts].[UMID],[dbo].[C_Contacts].[FirstName],[dbo].[C_Contacts].[LastName],[dbo].[C_Contacts].[Birthday],[dbo].[C_Contacts].[Photo],[dbo].[C_Contacts].[Remarks],[dbo].[C_Contacts].[Ver],[dbo].[C_Contacts].[InsTime],[dbo].[C_Contacts].[UpdTime] from ' + @tableName + ' where UMID ='+Convert(varchar(30),@UID)
set @StartTime = GETDATE();
while(@i<@max)
begin
execute(@sql)
set @i = @i+1
end
set @EndTime = GETDATE();
set @span3 = convert(varchar(30),DATEDIFF(MS,@StartTime,@EndTime))


print '测试select * 处理完成!共耗时: ' + @span1 +' ms'
print '测试select [字段名] 处理完成!共耗时: ' + @span2 +' ms'
print '测试select [数据库名].[架构名].[表名].[字段名] 处理完成!共耗时: ' + @span3 +' ms'
print '----------------------------'
print @span1
print @span2
print @span3

三、结果

每种情况分别测试5次,取平均值,得到以下的结果:

表名 select语句 第1次 第2次 第3次 第4次 第5次 平均值
[数据库名].[架构名].[表名] 测试select * 4166 4340 4260 4246 4216 4245.6
测试select [字段名] 4816 4946 4756 4793 4853 4832.8
测试select [数据库名].[架构名].[表名].[字段名] 5523 5293 5533 5213 5290 5370.4
[架构名].[表名] 测试select * 4576 4193 4326 4206 4226 4305.4
测试select [字段名] 5030 4860 4806 4920 4803 4883.8
测试select [数据库名].[架构名].[表名].[字段名] 5266 5173 5413 5156 5253 5252.2
[表名] 测试select * 4516 4206 4250 4203 4293 4293.6
测试select [字段名] 4780 4766 4880 4790 4870 4817.2
测试select [数据库名].[架构名].[表名].[字段名] 5276 5446 5370 5270 5240 5320.4

四、结论

1.直接使用select * 比使用select [字段名] 和 测试select [数据库名].[架构名].[表名].[字段名] 性能要好.

2.select语句中的表名用[数据库名].[架构名].[表名]的形式,比用[表名] 和 [架构名].[表名] 性能要好.


五、原因分析

1.select语句中加入数据名,架构名会加大sql语句的长度,sql编译时会增加复杂度,所以时间偏长.

2.表名用[数据库名].[架构名].[表名]编译时可以减少表名匹配的时间,所以时间较少.

不知道我的分析有无道理,也不知道数据内部对sql脚本的处理及编译是怎样的一个流程,期待高手作答.


专注于机器学习、前端相关邻域。关注 全栈深入 公众号查看更多硬核文章。
原文地址:https://www.cnblogs.com/janas/p/2317342.html