SQL Server Parameter Sniffing及其改進(jìn)方法
SQL Server 在處理存儲(chǔ)過(guò)程的時(shí)候,為了節(jié)省編譯時(shí)間,是一次編譯,多次重用。當(dāng)?shù)谝淮芜\(yùn)行時(shí)代入值產(chǎn)生的執(zhí)行計(jì)劃,不適用后續(xù)代入的參數(shù)時(shí),就產(chǎn)生了parameter sniffing問(wèn)題。 create procedure Sniff1(@i int) as SELECT count(b.SalesOrderID),sum(p.weight) from [Sale
SQL Server 在處理存儲(chǔ)過(guò)程的時(shí)候,為了節(jié)省編譯時(shí)間,是一次編譯,多次重用。當(dāng)?shù)谝淮芜\(yùn)行時(shí)代入值產(chǎn)生的執(zhí)行計(jì)劃,不適用后續(xù)代入的參數(shù)時(shí),就產(chǎn)生了parameter sniffing問(wèn)題。
create procedure Sniff1(@i int) as SELECT count(b.SalesOrderID),sum(p.weight) from [Sales].[SalesOrderHeader] a inner join [Sales].[SalesOrderDetail] b on a.SalesOrderID = b.SalesOrderID inner join Production.Product p on b.ProductID = p.ProductID where a.SalesOrderID =@i; go DBCC FREEPROCCACHE exec Sniff1 50000; exec Sniff1 75124; go

Parameter Sniffing問(wèn)題發(fā)生不頻繁,只會(huì)發(fā)生在數(shù)據(jù)分布不均勻或者代入?yún)?shù)值不均勻的情況下。現(xiàn)在,我們就來(lái)探討下如何解決這類(lèi)問(wèn)題。
1. 使用Exec() 方式運(yùn)行動(dòng)態(tài)SQL
create procedure Nosniff1(@i int) as declare @cmd varchar(1000); set @cmd = 'SELECT count(b.SalesOrderID),sum(p.weight) from [Sales].[SalesOrderHeader] a inner join [Sales].[SalesOrderDetail] b on a.SalesOrderID = b.SalesOrderID inner join Production.Product p on b.ProductID = p.ProductID where a.SalesOrderID ='; exec(@cmd+@i); go

exec Nosniff1 50000;

exec Nosniff1 75124;
從上述trace中可以看到,在執(zhí)行查詢(xún)語(yǔ)句之前,都有SP: CacheInsert事件,SQL Server做了動(dòng)態(tài)編譯,根據(jù)變量的值,都正確的預(yù)估了結(jié)果集,給出了不同的執(zhí)行計(jì)劃。
2. 使用本地變量
create procedure Nosniff2(@i int) as declare @iin int; set @iin=@i SELECT count(b.SalesOrderID),sum(p.weight) from [Sales].[SalesOrderHeader] a inner join [Sales].[SalesOrderDetail] b on a.SalesOrderID = b.SalesOrderID inner join Production.Product p on b.ProductID = p.ProductID where a.SalesOrderID =@iin; go
exec Nosniff2 50000;


exec Nosniff2 75124;


如上一篇文章所述,使用本地變量,參數(shù)值在存儲(chǔ)過(guò)程語(yǔ)句執(zhí)行過(guò)程中得到,SQL Server在運(yùn)行時(shí)不知道變量的值,會(huì)根據(jù)一個(gè)預(yù)估值進(jìn)行編譯,給出一個(gè)折中的執(zhí)行計(jì)劃。
3. 使用Query Hint,指定執(zhí)行計(jì)劃
在 SELECT、DELETE、UPDATE 和 MERGE 語(yǔ)句最后加上OPTION ( [ ,...n ] ),對(duì)執(zhí)行計(jì)劃進(jìn)行指導(dǎo)。當(dāng)數(shù)據(jù)庫(kù)管理員知道問(wèn)題所在時(shí),可以通過(guò)hint引導(dǎo)SQL Server生成一個(gè)對(duì)所有變量都不太差的執(zhí)行計(jì)劃。
以上所述是小編給大家介紹的SQL Server Parameter Sniffing及其改進(jìn)方法,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
delete誤刪數(shù)據(jù)使用SCN號(hào)恢復(fù)(推薦)
這篇文章主要介紹了使用scn號(hào)恢復(fù)誤刪數(shù)據(jù)問(wèn)題,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12
MSSQL存儲(chǔ)過(guò)程學(xué)習(xí)筆記一 關(guān)于存儲(chǔ)過(guò)程
在寫(xiě)筆記之前,首先需要整理好這些概念性的東西,否則的話,就會(huì)在概念上產(chǎn)生陌生或者是混淆的感覺(jué)。2011-05-05
用sql語(yǔ)句實(shí)現(xiàn)分離和附加數(shù)據(jù)庫(kù)的方法
對(duì)于分離一個(gè)數(shù)據(jù)庫(kù)來(lái)說(shuō),我們可以用Manage Studio界面或者存儲(chǔ)過(guò)程。但是對(duì)于每一種方法都必須保證沒(méi)有用戶(hù)使用這個(gè)數(shù)據(jù)庫(kù).接下來(lái)所講的都是對(duì)于用命令來(lái)分離或附加一個(gè)數(shù)據(jù)庫(kù)。2010-03-03
SqlServer2012中LEAD函數(shù)簡(jiǎn)單分析
SQL SERVER 2012 T-SQL新增幾個(gè)聚合函數(shù): FIRST_VALUE LAST_VALUE LEAD LAG,今天我們首先來(lái)簡(jiǎn)單分析下LEAD,希望對(duì)大家有所幫助,能夠盡快熟悉這個(gè)聚合函數(shù)2014-08-08
Sql Server中清空所有數(shù)據(jù)表中的記錄
我這里介紹的是刪除數(shù)據(jù)庫(kù)的所有數(shù)據(jù),因?yàn)閿?shù)據(jù)之間可能形成相互約束關(guān)系,刪除操作可能陷入死循環(huán),二是這里使用了微軟未正式公開(kāi)的sp_MSForEachTable存儲(chǔ)過(guò)程2013-10-10
分享Sql Server 存儲(chǔ)過(guò)程使用方法
這篇文章主要介紹了分享Sql Server 存儲(chǔ)過(guò)程使用方法的相關(guān)資料,需要的朋友可以參考下2022-09-09
sql server實(shí)現(xiàn)分頁(yè)的方法實(shí)例分析
這篇文章主要介紹了sql server實(shí)現(xiàn)分頁(yè)的方法,結(jié)合實(shí)例形式總結(jié)分析了SQL Server實(shí)現(xiàn)分頁(yè)功能的常用sql語(yǔ)句,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2017-03-03

