源自《Microsoft SQL Server 2005技术内幕:T-SQL程序设计》7.4 编译、重新编译和重用执行计划
示例如下:(表orders 的第一个字段"orderdate datetime"上建有索引), 第1个存储过程生成的执行计划是“全表扫描”,第2,3个生成的是“索引扫描”,推荐第3种。
create proc p_getorders_1
@d as int = 0
as
declare @odate as datetime;
set @odate = dateadd(day, -@d, convert(varchar(8), getdate(), 112));
select orderid, customerid, employeeid, orderdate from orders
where orderdate >= @odate; --这个是局部变量
go
create proc p_getorders_2
@d as int = 0
as
select orderid, customerid, employeeid, orderdate from orders
where orderdate >= dateadd(day, -@d, convert(varchar(8), getdate(), 112)); --这个是传入参数的计算表达式
go
create proc p_getorders_3
@odate as datetime
as
select orderid, customerid, employeeid, orderdate from orders
where orderdate >= @odate; --这个是传入参数
go
查询优化器“知道”输入参数的值,就能够生成适合该输入的执行计划;然而,当查询中引用局部变量时,查询优化器无法“嗅探”出变量的内容,当它在优化查询计划时,它必须猜测。这些局部变量是在批处理中还是在存储过程中都无关紧要。
很明显,如果你不了解这个问题而且没有采取纠正措施将导致性能低下的计划。