SQL基礎(chǔ)-執(zhí)行計(jì)劃-源動(dòng)力

什么是執(zhí)行計(jì)劃

執(zhí)行計(jì)劃:是查詢優(yōu)化器分析語(yǔ)句后,生成的一種確定性訪問(wèn)所需數(shù)據(jù)的最高效方式裸卫。

執(zhí)行計(jì)劃的輸入:

  • 查詢語(yǔ)句文本
  • 相關(guān)表, 約束, 索引定義
  • 數(shù)據(jù)庫(kù)的統(tǒng)計(jì)信息
  • 提示
  • 數(shù)據(jù)庫(kù)的優(yōu)化器參數(shù)設(shè)置

執(zhí)行計(jì)劃定義了:

  • 訪問(wèn)源表的順序
    數(shù)據(jù)庫(kù)服務(wù)器一般可以按許多不同的序列訪問(wèn)基表以生成結(jié)果集仿贬。

  • 用于從每個(gè)表提取數(shù)據(jù)的方法
    訪問(wèn)每個(gè)表中的數(shù)據(jù)一般也有不同的方法。 如果只需要有特定鍵值的幾行墓贿,數(shù)據(jù)庫(kù)服務(wù)器可以使用索引瞧捌。 如果需要表中的所有行附较,數(shù)據(jù)庫(kù)服務(wù)器則可以忽略索引并執(zhí)行表掃描。 如果需要表中的所有行葵礼,而有一個(gè)索引的鍵列在 ORDER BY中柱告,則執(zhí)行索引掃描而非表掃描可能會(huì)省去對(duì)結(jié)果集的單獨(dú)排序苛萎。 如果表很小硅确,則對(duì)該表的幾乎所有訪問(wèn)來(lái)說(shuō)烧颖,表掃描可能都是最有效的方法。

  • 用于計(jì)算的方法代嗤,以及如何對(duì)每個(gè)表中的數(shù)據(jù)進(jìn)行篩選、聚合和排序的方法
    從表訪問(wèn)數(shù)據(jù)時(shí)缠借,可以使用不同的方法對(duì)數(shù)據(jù)進(jìn)行計(jì)算干毅,例如,計(jì)算標(biāo)量值泼返,以及對(duì)查詢文本中定義的數(shù)據(jù)進(jìn)行聚合和排序(例如硝逢,使用 GROUP BY 或 ORDER BY 子句時(shí)),以及如何篩選數(shù)據(jù)(例如在使用 WHERE 或 HAVING 子句時(shí))绅喉。

執(zhí)行計(jì)劃生成

從潛在的多個(gè)可能的計(jì)劃中選擇一個(gè)執(zhí)行計(jì)劃的過(guò)程稱為“優(yōu)化”渠鸽。

SQL Server 查詢優(yōu)化器是基于成本的優(yōu)化器。 就所使用的計(jì)算資源量而言柴罐,每個(gè)可能的執(zhí)行計(jì)劃都具有相關(guān)成本徽缚。 查詢優(yōu)化器必須分析可能的計(jì)劃并選擇一個(gè)預(yù)計(jì)成本最低的計(jì)劃。

查詢優(yōu)化器不會(huì)分析所有的可能組合革屠, 而是使用復(fù)雜的算法查找一個(gè)執(zhí)行計(jì)劃:其成本合理地接近最低可能成本凿试。

SQL Server 查詢優(yōu)化器不只選擇資源成本最低的執(zhí)行計(jì)劃,還選擇能將結(jié)果最快地返回給用戶且資源成本合理的計(jì)劃似芝。

SQL Server 查詢優(yōu)化器在估計(jì)用于從表或索引中提取信息的不同方法所需的資源成本時(shí)那婉,依賴于分發(fā)內(nèi)容統(tǒng)計(jì)信息。如果索引統(tǒng)計(jì)信息不是當(dāng)前的党瓮,則查詢優(yōu)化器可能無(wú)法對(duì)表的當(dāng)前狀態(tài)做出最佳選擇详炬。

查看執(zhí)行計(jì)劃

  • 估計(jì)的執(zhí)行計(jì)劃

不實(shí)際運(yùn)行SQL語(yǔ)句,不包含任何運(yùn)行時(shí)信息

image.png
  • 實(shí)際執(zhí)行計(jì)劃

實(shí)際運(yùn)行SQL語(yǔ)句寞奸,包含處理的行數(shù)呛谜、經(jīng)過(guò)的時(shí)間在跳、CPU、內(nèi)存 和 I/O 使用情況等

image.png

查看執(zhí)行計(jì)劃

顯示分析呻率、編譯和執(zhí)行各語(yǔ)句所需的毫秒數(shù)
SET STATISTICS TIME ON

當(dāng) SET STATISTICS TIME 為 ON 時(shí)硬毕,會(huì)顯示語(yǔ)句的時(shí)間統(tǒng)計(jì)信息。為 OFF 時(shí)礼仗,不顯示時(shí)間統(tǒng)計(jì)信息吐咳。
SET STATISTICS TIME 的設(shè)置是在執(zhí)行或運(yùn)行時(shí)設(shè)置,而不是在分析時(shí)設(shè)置元践。

若要使用 SET STATISTICS TIME韭脊,用戶必須具有執(zhí)行 Transact-SQL 語(yǔ)句的相應(yīng)權(quán)限。但不需要 SHOWPLAN 權(quán)限单旁。

image.png

顯示語(yǔ)句生成的磁盤(pán)活動(dòng)量的信息
SET STATISTICS IO ON

image.png

掃描計(jì)數(shù):索引或表掃描次數(shù)

邏輯讀然Ω帷:數(shù)據(jù)緩存中讀取的頁(yè)數(shù)

物理讀取:從磁盤(pán)中讀取的頁(yè)數(shù)

預(yù)讀: 為進(jìn)行查詢而放入緩存的頁(yè)數(shù)

lob邏輯讀认蠡搿:從數(shù)據(jù)緩存讀取的頁(yè)數(shù)蔫饰。 包括 text、ntext愉豺、image篓吁、varchar(max)、 nvarchar(max)蚪拦、varbinary(max) 或列存儲(chǔ)索引頁(yè)

lob物理讀日燃簟:從磁盤(pán)讀取的頁(yè)數(shù)。 包括 text驰贷、ntext盛嘿、image、varchar(max)括袒、 nvarchar(max)次兆、varbinary(max) 或列存儲(chǔ)索引頁(yè)

lob預(yù)讀:為進(jìn)行查詢而放入緩存的頁(yè)數(shù)。 包括 text锹锰、ntext类垦、image、varchar(max)城须、 nvarchar(max)蚤认、varbinary(max) 或列存儲(chǔ)索引頁(yè)

image.png
  • 按照從右到左、從上到下的方式閱讀執(zhí)行計(jì)劃糕伐。
  • 箭頭寬度與箭頭數(shù)據(jù)量成正比砰琢。
  • 最左側(cè)的運(yùn)算符中可以查看該執(zhí)行計(jì)劃的緩存大小。
  • 表運(yùn)算符中估計(jì)行數(shù)與實(shí)際行數(shù)是否一致(統(tǒng)計(jì)信息是否過(guò)期)
image.png
  • 執(zhí)行 Transact-SQL 語(yǔ)句的適當(dāng)權(quán)限。
  • 對(duì)包含 Transact-SQL 語(yǔ)句所引用對(duì)象的所有數(shù)據(jù)庫(kù)的 SHOWPLAN 權(quán)限陪汽。

運(yùn)算符解釋:
https://docs.microsoft.com/zh-cn/previous-versions/sql/sql-server-2008-r2/ms191158(v=sql.105)

看懂執(zhí)行計(jì)劃

image.png
image.png
image.png
image.png
image.png

嵌套循環(huán)聯(lián)接(Nested Loops Join)

嵌套循環(huán)聯(lián)接使用一個(gè)聯(lián)接輸入作為外部輸入表训唱,另一個(gè)作為內(nèi)部輸入表。外部輸入表是執(zhí)行計(jì)劃中上面的輸入挚冤,而內(nèi)部輸入表是下面的輸入表况增。外部循環(huán)逐行消費(fèi)外部輸入表。內(nèi)部循環(huán)為每個(gè)外部行執(zhí)行一次训挡,搜索內(nèi)部輸入表的匹配行澳骤。

image.png

哈希聯(lián)接(Hash Join)

哈希聯(lián)接運(yùn)算符通過(guò)計(jì)算其生成輸入中每行的哈希值生成哈希表。對(duì)于聯(lián)接澜薄,使用第一個(gè)(頂端)輸入生成哈希表为肮,使用第二個(gè)(底端)輸入探測(cè)哈希表。按聯(lián)接類型規(guī)定的模式輸出匹配項(xiàng)(或不匹配項(xiàng))肤京。

image.png

合并聯(lián)接(Merge Join)

合并聯(lián)接要求兩個(gè)聯(lián)接輸入在合并列上排序颊艳,這將在聯(lián)接條件中定義。如果兩個(gè)聯(lián)接上有索引忘分,那么聯(lián)接輸入由該索引排序棋枕。因?yàn)槊總€(gè)聯(lián)接輸入都被排序,合并排序從每個(gè)輸入得到一行比較是否相等妒峦,如果它們相等戒悠,匹配的行被生成。這個(gè)過(guò)程重復(fù)直到所有行都被處理舟山。

image.png
image.png

分析執(zhí)行計(jì)劃及優(yōu)化

隱式轉(zhuǎn)換

SELECT TOP 10000 u.UserCode,u.UserName,o.HostIP,o.FunctionName
FROM myUser u 
INNER JOIN myOperLog o ON o.BUGUID = u.BUGUID
WHERE o.HostIP='192.168.0.34'
AND u.UserName='售樓部'

image.png
image.png
image.png

書(shū)簽查找(鍵查找)

image.png
image.png
image.png
image.png
image.png
image.png

臨界點(diǎn)是查詢計(jì)劃“提示”從尋找不覆蓋的非聚集索引到掃描聚集索引或堆的閾值。
基本公式并不是硬性的規(guī)則卤恳,因?yàn)檫€有其他各種影響因素累盗,它是這樣的:

  • 當(dāng)估計(jì)行數(shù)超過(guò)表中頁(yè)數(shù)的33%時(shí),通常會(huì)出現(xiàn)聚集索引(或表)掃描突琳。
  • 當(dāng)估計(jì)行數(shù)低于表中頁(yè)的25%時(shí)若债,通常會(huì)出現(xiàn)非群集查找加鍵查找。
  • 在25%到33%之間拆融,它可以走任何一條路蠢琳。
image.png

參數(shù)嗅探

image.png
image.png
image.png

重編譯

根據(jù)數(shù)據(jù)庫(kù)新?tīng)顟B(tài)的不同,數(shù)據(jù)庫(kù)中的某些更改可能導(dǎo)致執(zhí)行計(jì)劃效率降低或無(wú)效镜豹。
SQL Server 將檢測(cè)到使執(zhí)行計(jì)劃無(wú)效的更改傲须,并將計(jì)劃標(biāo)記為無(wú)效。
此后趟脂,必須為執(zhí)行查詢的下一個(gè)連接重新編譯新的計(jì)劃泰讽。
導(dǎo)致計(jì)劃無(wú)效的情況包括:

  • 對(duì)查詢所引用的表或視圖進(jìn)行更改(ALTER TABLE 和 ALTER VIEW)。
  • 對(duì)單個(gè)過(guò)程進(jìn)行更改,這將從緩存中刪除該過(guò)程的所有計(jì)劃 (ALTER PROCEDURE)已卸。
  • 對(duì)執(zhí)行計(jì)劃所使用的任何索引進(jìn)行更改佛玄。
  • 對(duì)執(zhí)行計(jì)劃所使用的統(tǒng)計(jì)信息進(jìn)行更新,這些更新可能是從語(yǔ)句(如 UPDATE STATISTICS)顯式生成累澡,也可能是自動(dòng)生成的梦抢。
  • 刪除執(zhí)行計(jì)劃所使用的索引。
  • 顯式調(diào)用 sp_recompile愧哟。
  • 對(duì)鍵進(jìn)行大量更改(這些更改是對(duì)查詢所引用的表進(jìn)行修改的其他用戶執(zhí)行 INSERT 或 DELETE 語(yǔ)句所產(chǎn)生的)奥吩。
  • 對(duì)于帶觸發(fā)器的表,如果插入的或刪除的表內(nèi)的行數(shù)顯著增長(zhǎng)翅雏。
  • 使用 WITH RECOMPILE 選項(xiàng)執(zhí)行存儲(chǔ)過(guò)程圈驼。

執(zhí)行計(jì)劃分析優(yōu)化步驟

1、找到邏輯讀取次數(shù)最多的表望几、執(zhí)行計(jì)劃中開(kāi)銷最大的查詢

2绩脆、在圖形執(zhí)行計(jì)劃中找到對(duì)應(yīng)的表的運(yùn)算符,不是聚集索引查找或索引查找的橄抹,如堆表靴迫、聚集索引掃描、鍵查找楼誓、一個(gè)表使用了2個(gè)索引關(guān)聯(lián)取數(shù)等玉锌,結(jié)合表的數(shù)據(jù)量和現(xiàn)有索引情況嘗試優(yōu)化,如新建缺失索引(執(zhí)行計(jì)劃中建議的缺失索引不應(yīng)照搬疟羹,應(yīng)分析后再創(chuàng)建或修改現(xiàn)有索引主守,同時(shí)應(yīng)刪除缺失索引中的聚集鍵),修改索引為包含索引等(表數(shù)據(jù)量小的情況下榄融,索引掃描可能更優(yōu)于索引查找)

3参淫、索引無(wú)法提高性能的情況下,檢查估計(jì)行數(shù)與實(shí)際行數(shù)的差別愧杯,更新統(tǒng)計(jì)信息涎才。還應(yīng)分析執(zhí)行時(shí)間長(zhǎng)的SQL語(yǔ)句,修改SQL語(yǔ)句的寫(xiě)法力九,將SELECT子句中的子查詢耍铜、自定義標(biāo)量函數(shù)(串行)、APPLY運(yùn)算符等改寫(xiě)為JOIN聯(lián)接跌前,盡量減少中間結(jié)果的數(shù)據(jù)量棕兼,如使用CTE、臨時(shí)表等抵乓,盡量少用表變量程储,表變量不創(chuàng)建統(tǒng)計(jì)信息蹭沛,會(huì)導(dǎo)致執(zhí)行計(jì)劃不準(zhǔn)確

4、重復(fù)步驟1-3章鲤,直至圖形執(zhí)行計(jì)劃中每個(gè)表對(duì)應(yīng)的運(yùn)算符基本為聚集索引查找或索引查找

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末摊灭,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子败徊,更是在濱河造成了極大的恐慌帚呼,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,539評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件皱蹦,死亡現(xiàn)場(chǎng)離奇詭異煤杀,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)沪哺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門(mén)沈自,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人辜妓,你說(shuō)我怎么就攤上這事枯途。” “怎么了籍滴?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,871評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵酪夷,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我孽惰,道長(zhǎng)晚岭,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,963評(píng)論 1 295
  • 正文 為了忘掉前任勋功,我火速辦了婚禮坦报,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘狂鞋。我一直安慰自己片择,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評(píng)論 6 393
  • 文/花漫 我一把揭開(kāi)白布要销。 她就那樣靜靜地躺著,像睡著了一般夏块。 火紅的嫁衣襯著肌膚如雪疏咐。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,763評(píng)論 1 307
  • 那天脐供,我揣著相機(jī)與錄音浑塞,去河邊找鬼。 笑死政己,一個(gè)胖子當(dāng)著我的面吹牛酌壕,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,468評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼卵牍,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼果港!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起糊昙,我...
    開(kāi)封第一講書(shū)人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤辛掠,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后释牺,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體萝衩,經(jīng)...
    沈念sama閱讀 45,850評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評(píng)論 3 338
  • 正文 我和宋清朗相戀三年没咙,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了猩谊。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,144評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡祭刚,死狀恐怖牌捷,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情袁梗,我是刑警寧澤宜鸯,帶...
    沈念sama閱讀 35,823評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站遮怜,受9級(jí)特大地震影響淋袖,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜锯梁,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評(píng)論 3 331
  • 文/蒙蒙 一即碗、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧陌凳,春花似錦剥懒、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,026評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至充岛,卻和暖如春保檐,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背崔梗。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,150評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工夜只, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蒜魄。 一個(gè)月前我還...
    沈念sama閱讀 48,415評(píng)論 3 373
  • 正文 我出身青樓扔亥,卻偏偏與公主長(zhǎng)得像场躯,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子旅挤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容