我编写了2个存储过程,根据参数读取相同的数据,一个使用静态查询sp_Order_Read1
,另一个使用动态sp_Order_Read2
。他们读取了Orders
示例数据库中Northwind
表的数据;在SQL Server 2012
。
sp_Order_Read1
:
create proc sp_Order_Read1 @OrderID int, @page int, @pageLength int
as begin
if @OrderID is null
begin
if @page is not null and @pageLength is not null
select OrderID, CustomerID, EmployeeID, OrderDate, RequiredDate, ShippedDate, ShipVia, Freight, ShipName, ShipAddress, ShipCity, ShipRegion, ShipPostalCode, ShipCountry
from Orders o
order by o.OrderID
offset (@page - 1) * @pageLength rows
fetch next @pageLength rows only
else
select OrderID, CustomerID, EmployeeID, OrderDate, RequiredDate, ShippedDate, ShipVia, Freight, ShipName, ShipAddress, ShipCity, ShipRegion, ShipPostalCode, ShipCountry
from Orders o
end
else
begin
if @page is not null and @pageLength is not null
select OrderID, CustomerID, EmployeeID, OrderDate, RequiredDate, ShippedDate, ShipVia, Freight, ShipName, ShipAddress, ShipCity, ShipRegion, ShipPostalCode, ShipCountry
from Orders o
where o.OrderID = @OrderID
order by o.OrderID
offset (@page - 1) * @pageLength rows
fetch next @pageLength rows only
else
select OrderID, CustomerID, EmployeeID, OrderDate, RequiredDate, ShippedDate, ShipVia, Freight, ShipName, ShipAddress, ShipCity, ShipRegion, ShipPostalCode, ShipCountry
from Orders o
where o.OrderID = @OrderID
end
end
sp_Order_Read2
:
create proc sp_Order_Read2 @OrderID int, @page int, @pageLength int
as begin
declare @query nvarchar(max) = ''
if @OrderID is not null
begin
declare @OrderIDExpression nvarchar(max)
if IsNumeric(@OrderID) = 1
set @OrderIDExpression = @OrderID
else
set @OrderIDExpression = '''' + @OrderID + ''''
set @query += 'declare @OrderID int = ' + @OrderIDExpression + ';
'
end
if @page is not null and @pageLength is not null
begin
set @query += 'declare @page int = ' + convert(nvarchar(max), @page) + ';
declare @pageLength int = ' + convert(nvarchar(max), @pageLength) + ';
'
end
set @query +=
'select OrderID, CustomerID, EmployeeID, OrderDate, RequiredDate, ShippedDate, ShipVia, Freight, ShipName, ShipAddress, ShipCity, ShipRegion, ShipPostalCode, ShipCountry
from Orders o'
if @OrderID is not null
set @query += '
where'
if @OrderID is not null
set @query += '
OrderID = @OrderID'
if @page is not null and @pageLength is not null
set @query += '
order by o.OrderID
offset (@page - 1) * @pageLength rows
fetch next @pageLength rows only'
exec(@query)
end
* 请注意,我编写了一个为我生成静态/动态语法的工具,因此写入不是一件大事。
我无法决定哪种语法运行得更快,所以我决定测试它们。我创建了临时表#comparison
来保存结果。
create table #comparison
(
ID int identity,
One int,
Two int
)
测试就是这个剧本:
declare @counter int = 1
declare @count int = 50
declare @beginning1 datetimeoffset
declare @end1 datetimeoffset
declare @beginning2 datetimeoffset
declare @end2 datetimeoffset
while(@counter <= @count)
begin
set @beginning1 = sysdatetimeoffset()
exec sp_Order_Read1 null, 5, 50
set @end1 = sysdatetimeoffset()
set @beginning2 = sysdatetimeoffset()
exec sp_Order_Read2 null, 5, 50
set @end2 = sysdatetimeoffset()
insert #comparison (One, Two) values (datediff(microsecond, @beginning1, @end1), datediff(microsecond, @beginning2, @end2))
set @counter += 1
end
我跑了5次,每次看完这个查询后的结果:
select count(ID) as [Row Count], (sum(One) - sum(Two)) as [Difference] from #comparison
然后我将测试脚本中的顺序切换为:
declare @counter int = 1
declare @count int = 50
declare @beginning1 datetimeoffset
declare @end1 datetimeoffset
declare @beginning2 datetimeoffset
declare @end2 datetimeoffset
while(@counter <= @count)
begin
set @beginning2 = sysdatetimeoffset()
exec sp_Order_Read2 null, 5, 50
set @end2 = sysdatetimeoffset()
set @beginning1 = sysdatetimeoffset()
exec sp_Order_Read1 null, 5, 50
set @end1 = sysdatetimeoffset()
insert #comparison (One, Two) values (datediff(microsecond, @beginning1, @end1), datediff(microsecond, @beginning2, @end2))
set @counter += 1
end
我还运行了5次,每次运行后我都使用相同的查询查看了结果。测试结果如下:
Row Count Difference
---------------------------
100 439119
200 35963
300 2211699
400 14443
500 -2666605
--Reversed Excution Order--
600 5846095
700 13221704
800 21094312
900 28361390
1000 37526611
结果非常奇怪,对我不满意;所以,如果有人能帮助我决定哪种语法运行得更快,给出令人满意的推理,我会感激不尽。