Ένα από τα θέματα που σε κάποιες περιπτώσεις μας έχει ταλαιπωρήσει ιδιαίτερα αν δεν το γνωρίζουμε είναι το parameter sniffing.
Έχω κατά καιρούς διαβάσει και δει διάφορες προτάσεις για την αντιμετώπιση του.
Επειδή όμως δεν ήθελα απλά να το περιγράψω σε ένα ίσως μακροσκελές κείμενο αποφάσισα να το κάνω ένα web cast που ζωντανά δείχνω όλο το θέμα χωρίς slides αλλά με παραδείγματα.
Enjoy it.
Ο κώδικας του demo είναι
/*
Parameter Sniffing Demo
SQLSCHOOL GREECE
V1 18/2/2013
*/
use AdventureWorks2012;
go
select * from Sales.SalesOrderDetail
where ProductID=897;
go
select * from Sales.SalesOrderDetail
where ProductID=870;
go
if OBJECT_ID(N'spGetOrdersByProductID') > 0
drop proc spGetOrdersByProductID
go
create proc spGetOrdersByProductID(@pid int)
as
select * from Sales.SalesOrderDetail
where ProductID=@pid;
go
/*
Define the problem
*/
set statistics io on;
go
DBCC FREEPROCCACHE WITH NO_INFOMSGS;
GO
exec spGetOrdersByProductID 897;
go
exec spGetOrdersByProductID 870;
go
-- REVERSE ORDER
DBCC FREEPROCCACHE WITH NO_INFOMSGS;
GO
exec spGetOrdersByProductID 870;
go
exec spGetOrdersByProductID 897;
go
/*
Optimize for a typical parameter
*/
alter proc spGetOrdersByProductID (@pid int)
as
select * from Sales.SalesOrderDetail
where ProductID=@pid
option (optimize for (@pid=897));
go
DBCC FREEPROCCACHE WITH NO_INFOMSGS;
GO
exec spGetOrdersByProductID 870;
go
exec spGetOrdersByProductID 897;
go
/*
Optimize on every execution
*/
alter proc spGetOrdersByProductID (@pid int)
as
select * from Sales.SalesOrderDetail
where ProductID=@pid
option (recompile);
go
DBCC FREEPROCCACHE WITH NO_INFOMSGS;
GO
exec spGetOrdersByProductID 870;
go
exec spGetOrdersByProductID 897;
go
/*
Local Varibales and Optimize for Unknown
*/
alter proc spGetOrdersByProductID (@pid int)
as
DECLARE @P INT = @pid;
select * from Sales.SalesOrderDetail
where ProductID=@p;
go
DBCC FREEPROCCACHE WITH NO_INFOMSGS;
GO
exec spGetOrdersByProductID 870;
go
exec spGetOrdersByProductID 897;
go
alter proc spGetOrdersByProductID (@pid int)
as
select * from Sales.SalesOrderDetail
where ProductID=@pid
option (optimize for unknown);
go
DBCC FREEPROCCACHE WITH NO_INFOMSGS;
GO
exec spGetOrdersByProductID 870;
go
exec spGetOrdersByProductID 897;
go