亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 數據庫 > SQL Server > 正文

SQL Server中參數化SQL寫法遇到parameter sniff ,導致不合理執行計劃重用的快速解決方法

2024-08-31 01:04:00
字體:
來源:轉載
供稿:網友

parameter sniff問題是重用其他參數生成的執行計劃,導致當前參數采用該執行計劃非最優化的現象。想必熟悉數據的同學都應該知道,產生parameter sniff最典型的問題就是使用了參數化的SQL(或者存儲過程中使用了參數化)寫法,如果存在數據分布不均勻的情況下,正常情況下生成的執行計劃,在傳入在分布數據較多的參數的情況下,重用了正常參數生成的執行計劃,而這種緩存的執行計劃并非適合當前參數的一種情況。

這種情況,在實際業務中,出現的頻率還是比較高的,因為存儲過程一般都是采用參數化的寫法,這時,遇到分布不均勻的數據參數時,parameter sniff現象就出現了,這種問題還是比較讓人頭疼的。

具體parameter sniff產生的原因,我就不做過多的解釋了,解釋這個就顯得太low了

我舉個簡單的例子,模擬一下這個現象,說明參數化的存存儲過程是怎么寫的,存在哪些問題,又如何解決parameter sniff問題,

先創建一個測試環境:

create table ParameterSniffProblem(id int identity(1,1),CustomerId int,OrderId int,OrederStatus int,CreateDate Datetime,Remark varchar(200))declare @i int = 0while @i<500000beginINSERT INTO ParameterSniffProblem values (@i%10000,@i,RAND()*10,GETDATE()-RAND()*100,NEWID())set @i=@i+1end--假如某一個客戶有非常多的訂單,模擬數據分布不均勻的情況INSERT INTO ParameterSniffProblem values (6666,RAND()*100000,1,GETDATE()-RAND()*100,NEWID())GO 100000--創建正常的索引CREATE CLUSTERED INDEX IDX_CreateDate on ParameterSniffProblem(CreateDate)CREATE INDEX IDX_CustomerId ON ParameterSniffProblem(CustomerId)

參數化存儲過程的寫法:

在編寫存儲過程的時候,我們一般建議采用參數化的寫法,目的是為了減少存儲過程的編譯和加強執行計劃緩存的重用

大概是這樣子的

CREATE PROCEDURE [dbo].ParameterSniffTest ( @p_CustomerId int,@p_Status int,@p_FromDate datetime,@p_ToDate datetime) AS BEGINSET NOCOUNT ON DECLARE@Parm NVARCHAR(MAX),@sqlcommand NVARCHAR(MAX) = N''SET @sqlcommand = 'SELECT * FROM ParameterSniffProblem WHERE 1=1'     IF(@p_CustomerId IS NOT NULL)SET @sqlcommand = CONCAT(@sqlcommand,'AND CustomerId=@p_CustomerId ')IF(@p_Status IS NOT NULL)SET @sqlcommand = CONCAT(@sqlcommand,'AND OrederStatus=@p_Status ')IF(@p_FromDate IS NOT NULL)SET @sqlcommand = CONCAT(@sqlcommand,'AND CreateDate>=@p_FromDate ')IF(@p_ToDate IS NOT NULL)SET @sqlcommand = CONCAT(@sqlcommand,'AND CreateDate<=@p_ToDate ')    SET @Parm= '@p_CustomerId int,@p_Status   int,@p_FromDate  datetime,@p_ToDate   datetime '    EXEC sp_executesql @sqlcommand,@Parm,@p_CustomerId = @p_CustomerId,@p_Status = @p_Status,@p_FromDate = @p_FromDate,@p_ToDate = @p_ToDate ENDGO

Parameter Sniff問題:

這就潛在一個parameter sniff問題,

比如我查詢用戶ID=100的訂單信息,一個正常的分布的數據,存儲過程第一次編譯,這個執行計劃完全沒有問題,

sqlserver,parameter,sniff

如果我接著改變參數執行查詢用戶6666的信息,一個分布及其不均勻的數據,但是因為重用上面緩存的執行計劃,就出現parameter sniff問題了,這個執行計劃顯然是不合理的

IO就不看了,刻意造的例子

sqlserver,parameter,sniff

如果我清空執行計劃緩存,重新執行上述查詢,因為有了重編譯,執行計劃就是不這個樣子,對于CustomerID=6666這個參數來說,顯然走全表掃描代價要更小一點

sqlserver,parameter,sniff

想必這是一個開發中常見的問題給,我們參數化SQL就是為了讓不同參數的查詢重用執行計劃,但是很不幸,數據分布不均勻的時候,重用執行計劃恰恰又給數據庫造成了傷害,例中,如果是正常參數重用了分布較多數據的執行計劃,比如命名可以用到索引,結果是表掃描,后果會更嚴重。

那么,既想要盡可能的重用執行計劃,又要避免因為執行計劃重用產生parameter sniff問題,怎么辦?

我們知道問題在于@p_CustomerId身上,那么可不可以對有可能產生parameter sniff問題的@p_CustomerId不做參數化,直接拼湊在SQL中,如果@p_CustomerId變化了就重編譯SQL,也就是對傳入進來的@p_CustomerId重編譯

如果是@p_CustomerId不變,其他參數有變化,比如這里時間字段的變化,還可以享受參數化帶來的執行計劃重用的好處 也就是這樣處理 @p_CustomerId這個參數,直接把@p_CustomerId以字符串的方式平湊在SQL語句中,這樣的話,就相當于即席查詢了,不通過參數化的方式給CustomerId這個查詢條件字段賦值

IF(@p_CustomerId IS NOT NULL)SET @sqlcommand = CONCAT(@sqlcommand,'AND CustomerId= ',@p_CustomerId)

這樣再去執行存儲過程的時候,

帶入@p_CustomerId=1的時候,執行IDX_CustomerId的index seek

sqlserver,parameter,sniff

帶入@p_CustomerId=6666的時候,重編譯,執行計劃是全表掃描,避免重用上面生成的執行計劃,造成不合理的執行方式對效率以及數據庫服務器資源的消耗

sqlserver,parameter,sniff

這樣會盡可能的減少parameter sniff問題帶來的影響,當緩存了@p_CustomerId=1的執行計劃的時候,再次傳入@p_CustomerId=1,其他條件有較小的變化,比如時間字段上有改動,依然可以重用緩存的執行計劃,避免重編譯帶來的影響

結論:

這種方式于處理parameter sniff問題,當然不是完美的,肯定也有問題,我當然知道一旦@p_CustomerId不同就要重編譯

肯定會因為@p_CustomerId參數值不同,這樣的話,不可避免地增加了重編譯的機會,

但是卻不會因為不合理的執行計劃重用,帶來的parameter sniff問題

要知道一旦產生parameter sniff問題,大量的查詢用到不合理的執行計劃,會對整個服務器產生非常嚴重的影響,比如可能會產生大量的IO等

同時存在一個好處,比如第一次傳入@p_CustomerId=1,

再次傳入@p_CustomerId=1,其他條件有較小的變化,比如時間字段上有改動,依然可以重用緩存的執行計劃,避免重編譯帶來的影響當然我這里只是一個簡單的例子,實際應用中遠遠比這個復雜

比如分布的特別的多的數據有兩個特點,第一分布的標示不僅僅只有一個,第二分布不均的數據是動態的,有可能第一季度是A這部分數據占據大多數,有可能是第二季度B數據占絕大多數

所以很難采用Plan Guide的方式解決parameter sniff問題

這種方式可以在一定程度上也能夠重用緩存的執行計劃,可以減少(但不可避免)重編譯的次數

同時,這種方式與拼湊一個SQL字符串執行的即席查詢方式相比,同時還可以利用參數化帶來的其他好處,比如SQL注入等等

總結:

    parameter sniff問題的解決方式有很多,不一一啰嗦了

    最典型的就是強制重編譯,

    或者使用EXEC執行一個拼湊出來的字符串,這種方式屬于Adhoc查詢

    或者查詢提示,

    或者是使用本地變量,

      或者使用Plan Guide等等等等,

    每種方式都有他的局限性,至少到目前為止,還沒有一種十全十美的方式來解決parameter sniff問題

    遇到問題,解決方法有很多種,以最小的代價解決問題才是王道。

 

注:相關教程知識閱讀請移步到MSSQL教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
91精品国产色综合| 在线视频中文亚洲| 91精品国产高清久久久久久91| 欧美人与性动交| 57pao国产成人免费| 欧美又大粗又爽又黄大片视频| 亚洲美女在线看| 在线观看日韩av| 亚洲视频一区二区三区| 亚洲91av视频| 亚洲а∨天堂久久精品9966| 中文字幕在线国产精品| 中文字幕精品在线视频| 97成人精品视频在线观看| 国产精品久久久久久网站| 精品成人乱色一区二区| 国产精品va在线| 97国产成人精品视频| 午夜精品视频网站| 国产免费一区视频观看免费| 亚洲人成伊人成综合网久久久| 日韩欧美国产中文字幕| 精品日本高清在线播放| 亚洲欧美另类国产| 国模精品一区二区三区色天香| 中文字幕精品久久| 亚洲aⅴ日韩av电影在线观看| 国产精品v日韩精品| 日产日韩在线亚洲欧美| 欧美日韩黄色大片| 日韩美女写真福利在线观看| 中文精品99久久国产香蕉| 26uuu另类亚洲欧美日本老年| 欧美日本精品在线| 欧美精品在线播放| 亚洲国产精品女人久久久| 2019最新中文字幕| 久久777国产线看观看精品| 中文国产成人精品| 亚洲最大福利网站| 一区二区三区国产视频| 日韩中文字幕精品视频| 高清日韩电视剧大全免费播放在线观看| 国产精品久久久久久超碰| 亚洲а∨天堂久久精品喷水| 97精品国产97久久久久久| 一区二区三区动漫| 欧美精品一区二区三区国产精品| 国产精品国产三级国产aⅴ浪潮| 成人欧美一区二区三区黑人孕妇| 日韩精品免费在线| 亚洲成av人影院在线观看| 中文字幕视频在线免费欧美日韩综合在线看| 91爱视频在线| 久久久久久国产三级电影| 欧美亚洲另类视频| www.日本久久久久com.| 国产精品国产三级国产专播精品人| 亚州国产精品久久久| 亚洲欧美制服中文字幕| 成人xxxxx| 久久亚洲综合国产精品99麻豆精品福利| 蜜月aⅴ免费一区二区三区| 国产91精品久久久久| 色婷婷av一区二区三区在线观看| 亚洲精品v天堂中文字幕| 夜夜嗨av一区二区三区免费区| 欧美激情一二区| 国产一区二区三区中文| 国产免费一区二区三区在线观看| 亚洲视频一区二区三区| 97视频在线观看视频免费视频| 日韩中文字幕在线视频| 91chinesevideo永久地址| 国产精品99久久99久久久二8| 日韩精品欧美激情| 国产精品吹潮在线观看| 欧美黑人极品猛少妇色xxxxx| 一区二区三区动漫| 国产精品久久久久久超碰| 亚洲成色999久久网站| 国产精品v片在线观看不卡| 日韩激情av在线免费观看| 欧美视频在线观看免费| 色综合天天狠天天透天天伊人| 欧美极品美女电影一区| 少妇激情综合网| 日韩毛片中文字幕| 亚洲一区二区三区成人在线视频精品| 8x海外华人永久免费日韩内陆视频| 最新国产成人av网站网址麻豆| 亚洲精品国产精品国产自| 亚洲欧洲在线视频| 亚洲在线第一页| 欧美性生活大片免费观看网址| 91久久久久久久久久久久久| 国产69精品久久久久久| 国产精品久久色| 亚洲第一天堂av| 国产精品爽黄69天堂a| 中文字幕日韩欧美在线| 亚洲影视九九影院在线观看| 久久久久久这里只有精品| 欧美黄色片视频| 久久久亚洲国产天美传媒修理工| 国产精品91在线| 色婷婷综合久久久久中文字幕1| 日韩在线观看免费全| 国产精品国产自产拍高清av水多| 97成人精品视频在线观看| 欧美日在线观看| 69**夜色精品国产69乱| 欧美激情中文字幕乱码免费| 国产精品视频久久| 久久久精品视频成人| 久精品免费视频| 久久99亚洲精品| 亚洲一区二区自拍| 三级精品视频久久久久| 日韩免费在线观看视频| 亚洲精品在线看| 国产精品ⅴa在线观看h| 欧美激情三级免费| 国产日韩欧美在线| 国产成人精品av| 97在线免费观看视频| 国产主播喷水一区二区| 亚洲欧美日韩精品久久亚洲区| 国产精品网站视频| 亚洲a级在线播放观看| 久久亚洲精品小早川怜子66| 91精品中文在线| 国产成人+综合亚洲+天堂| 亚洲天堂日韩电影| 午夜精品久久久久久99热软件| 中文字幕v亚洲ⅴv天堂| 国产丝袜一区二区三区免费视频| 国产精品流白浆视频| 午夜精品美女自拍福到在线| 午夜免费日韩视频| 九九热最新视频//这里只有精品| www.久久撸.com| 日韩中文字幕免费| 日本精品视频在线播放| 国产一区二区黑人欧美xxxx| 国产精品一区二区久久久| 日本欧美在线视频| 午夜精品国产精品大乳美女| 成人福利在线观看| 中日韩美女免费视频网站在线观看| 国产精品成人观看视频国产奇米| 91在线视频免费| 欧美日本精品在线| 欧美成人黄色小视频| 亚洲色图欧美制服丝袜另类第一页| 欧美成人中文字幕在线| 欧美日韩一区二区三区在线免费观看| 亚洲精品免费av| 色综合色综合久久综合频道88| 亚洲精品小视频| 国产精品爽爽爽爽爽爽在线观看| www.亚洲免费视频| 亚洲最大的av网站| 国产精品成人品|