【SQLServer】使用SQL執(zhí)行計(jì)劃進(jìn)行性能調(diào)優(yōu)
當(dāng)前位置:點(diǎn)晴教程→知識管理交流
→『 技術(shù)文檔交流 』
SQL執(zhí)行計(jì)劃中會(huì)有許多跡象表明查詢中可能存在不良性能點(diǎn)。例如,與整體查詢成本相關(guān)的成本最高的最昂貴運(yùn)算符是查詢性能故障排除的良好起點(diǎn)。此外,后面跟著細(xì)箭頭的粗箭頭表示正在處理大量記錄并從一個(gè)運(yùn)算符流向另一個(gè)運(yùn)算符以檢索少量記錄,這也可能是缺少索引或性能問題的標(biāo)志。 在了解了本系列中討論的每個(gè)計(jì)劃運(yùn)算符的作用之后,你可以識別出由于額外開銷而降低查詢性能的額外運(yùn)算符。此外,用于掃描整個(gè)表或索引的Scan運(yùn)算符表明大多數(shù)情況下存在缺少索引、索引使用不當(dāng)或查詢不包含過濾條件。執(zhí)行計(jì)劃中查詢中性能問題的另一個(gè)標(biāo)志是執(zhí)行計(jì)劃警告。這些消息用于警告查詢的不同問題以進(jìn)行故障排除,例如tempdb溢出問題、缺少索引或錯(cuò)誤的基數(shù)估計(jì)。 要了解如何使用SQL執(zhí)行計(jì)劃來調(diào)整性能,讓我們通過我們的實(shí)例演示。在開始第一個(gè)示例之前,我們將使用以下create TABLE語句創(chuàng)建兩個(gè)新表:
然后使用ApexSQL Generate向每個(gè)表中插入100k條記錄
調(diào)優(yōu)簡單的查詢
調(diào)優(yōu)查詢性能的最佳方法是研究該查詢的SQL執(zhí)行計(jì)劃。執(zhí)行前面的查詢: 從生成的計(jì)劃中可以清楚地看出,SQL Server引擎掃描所有表行(100K 記錄)以檢索請求的數(shù)據(jù)(1 條記錄)。從三個(gè)跡象可以看出這一點(diǎn): 使用ApexSQL Plan,可以檢查查詢的執(zhí)行統(tǒng)計(jì)信息,例如該查詢的讀次數(shù)、持續(xù)時(shí)間和CPU成本,如下所示: 從計(jì)劃中得出的三個(gè)標(biāo)志將我們引向查詢性能不佳的主要原因,即EMP_Salary表中沒有索引,索引可以加快從該表中檢索數(shù)據(jù)的過程。我們將繼續(xù)使用下面的create INDEX語句在EMP_Salary表的EMP_ID列上創(chuàng)建索引:
…然后運(yùn)行相同的語句。 從生成的執(zhí)行計(jì)劃中可以看出,SQL Server Engine會(huì)直接在創(chuàng)建的索引中尋找請求的數(shù)據(jù),無需掃描整個(gè)底層表,Index Seek的成本降低到50%。此外,從Index Seek運(yùn)算符流向下一個(gè)運(yùn)算符的記錄數(shù)明顯減少,從箭頭的粗細(xì)可以看出,如下圖所示: 檢查執(zhí)行計(jì)劃的統(tǒng)計(jì)信息,將看到行數(shù)如何減少到2,而持續(xù)時(shí)間和CPU成本可以忽略不計(jì),如下所示: 如果深入查看之前的計(jì)劃,你會(huì)發(fā)現(xiàn)另一個(gè)性能問題的跡象,即額外昂貴的RID查找和嵌套循環(huán)運(yùn)算符。SQL Server引擎使用非聚集索引檢索EMP_ID列并返回基礎(chǔ)表以檢索其余列。這個(gè)問題可以通過創(chuàng)建一個(gè)覆蓋索引來解決,它允許SQL Server引擎從該有序的索引中檢索所有列,而無需檢查基礎(chǔ)表。 下面的create INDEX語句可用于為該查詢創(chuàng)建覆蓋索引:
運(yùn)行相同的select語句,將看到不再出現(xiàn)RID Lookup和Nested Loops運(yùn)算符,因?yàn)镾QL Server引擎在索引中找到了所有請求的數(shù)據(jù),如下所示:
調(diào)優(yōu)復(fù)雜查詢 我們看到了SQL執(zhí)行計(jì)劃如何幫助我們調(diào)優(yōu)簡單查詢的性能。它會(huì)以同樣的方式幫助我們進(jìn)行更復(fù)雜的查詢的調(diào)優(yōu)嗎? 讓我們刪除在EMP_Salaries表上創(chuàng)建的索引:
假設(shè)我們需要調(diào)整以下查詢的性能,該查詢連接之前創(chuàng)建的兩個(gè)EMP測試表,以檢索員工的信息:
如果執(zhí)行查詢,你會(huì)從生成的計(jì)劃中看到一些性能問題的跡象,比如Table Scan運(yùn)算符,由于掃描了整個(gè)底層表;粗箭頭,由于大量的行在運(yùn)算符之間流動(dòng)以及額外昂貴的運(yùn)算符,例如Hash Match運(yùn)算符,如下面的SQL執(zhí)行計(jì)劃所示: 查看查詢的執(zhí)行統(tǒng)計(jì),會(huì)看到讀取次數(shù)多,持續(xù)時(shí)間長,CPU消耗高,如下圖: 在執(zhí)行計(jì)劃的上半部分,將看到一條綠色的create INDEX語句,用于推薦的索引,這將提高查詢的性能,如下所示: 如果我們創(chuàng)建了建議的索引,那么再次執(zhí)行語句。生成的SQL執(zhí)行計(jì)劃將顯示,Table Scan運(yùn)算符更改為Index Seek運(yùn)算符。但是箭頭仍然是粗的,這是正常的行為,因?yàn)闆]有從粗箭頭到細(xì)箭頭的過渡,如下所示: 執(zhí)行持續(xù)時(shí)間和CPU 成本的有點(diǎn)降低了,如下查詢的執(zhí)行統(tǒng)計(jì)所示: 可以通過更好的方式編寫查詢來實(shí)現(xiàn)查詢性能的增強(qiáng)。例如,可以使用限制返回行數(shù)的TOP子句來減小箭頭的粗細(xì)。另一方面,可以通過使用以下create INDEX語句在EMP_Salaries表上創(chuàng)建新索引來刪除過濾器運(yùn)算符:
而生成的執(zhí)行計(jì)劃,經(jīng)過這些修改后,將是這樣的: 該文章在 2023/11/27 11:52:27 編輯過 |
關(guān)鍵字查詢
相關(guān)文章
正在查詢... |