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