SQL Server里書簽查找的性能傷害
在我的博客上,以前我經常談到SQL Serverl里的書簽查找,還有它們帶來的很多問題。在今天的文章里,我想從性能角度進一步談下書簽查找,還有它們如何拉低你整個SQL Server性能。
書簽查找——反復循環(huán)
如果你的非聚集索引不是個覆蓋非聚集索引,SQL Server的查詢優(yōu)化器會引入書簽查找。對于從非聚集索引你返回的每一行,SQL Server需要在聚集索引里或堆表里進行額外的查找操作。
例如當你的的聚集索引包含3層,為了返回必要的信息,對于每一行,你需要3頁額外的讀取。因此,查詢優(yōu)化器再執(zhí)行計劃里選擇書簽查找操作,僅在有意義的時候發(fā)生——基于你查詢的選擇度。下圖展示了有書簽查找操作的執(zhí)行計劃。
通常人們不會太關注書簽查找,因為它們只執(zhí)行幾次。如果你的查詢選擇度太低,查詢優(yōu)化器會用聚集索引掃描或表掃描運算符直接掃描整個表。但只在SQL Server重用緩存的執(zhí)行計劃,這個計劃是有多次不同運行值,包含書簽查找的(基于最初提供的輸入值),因此這個情況很容易發(fā)生,書簽查找反復執(zhí)行。
為了演示這個性能問題,接下來的查詢我指定查詢優(yōu)化器使用特定的非聚集索引。查詢本身返回80000行,因為對于每個查詢執(zhí)行,SQL Server需要進行書簽查找80000次——反復執(zhí)行。
CREATE PROCEDURE RetrieveData AS SELECT * FROM Table1 WITH (INDEX(idxTable1_Column2)) WHERE Column3 = 2 GO
下圖展示了查詢執(zhí)行后的實際執(zhí)行計劃。
執(zhí)行計劃看起來非??植溃ú樵儍?yōu)化器甚至啟用了并行計劃?。?,因為書簽查找運算符這里執(zhí)行了80000次,查詢本身產生了超過165000個邏輯讀!(邏輯讀個數可以從STATISTIC IO里獲?。?。
接下來向你展示下,當你有很多并行用戶執(zhí)行這個糟糕查詢時,SQL Server會發(fā)生什么。我會使用ostress.exe(RML工具的一部分)來模擬100個并行用戶的查詢。
ostress.exe -Q”EXEC BookmarkLookupsPerformance.dbo.RetrieveData” -n100 -q
在我的測試系統(tǒng)上花費了近15秒來完成100個并行查詢。在此期間,CPU占用很高,因為SQL Server需要嵌套循環(huán)運算符來進行書簽查找操作。嵌套循環(huán)操作當然很占CPU資源。
現在讓我們修改索引設計,為這個查詢創(chuàng)建覆蓋非聚集索引。有了非聚集索引,查詢優(yōu)化器不需要再執(zhí)行計劃里進行書簽查找。一個非聚集索引查找就可以返回同樣的結果:
CREATE NONCLUSTERED INDEX idxTable1_Column2 ON Table1(Column3) INCLUDE (Column2) WITH (DROP_EXISTING = ON) GO
這次當我們再次用ostress.exe執(zhí)行同個查詢,我們看到每個查詢在5秒內完成。和我們剛才看到的15秒有很大的區(qū)別。這就是覆蓋非聚集索引的威力:在我們查詢里氣門請求的數據都可以在非聚集索引里直接找到,因此書簽查找就可以避免。
小結
在這個文章里我向你展示了不好的書簽查找會傷及性能。因此,對于重要的查詢快速完成查詢非常重要——而使用并行的書簽查找的執(zhí)行計劃并不是好的選擇。這里覆蓋非聚集索引可以幫到你。下次設計索引時可以考慮下這個方法。
以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持我們!
上一篇:SQLServer數據庫中開啟CDC導致事務日志空間被占滿的原因
欄 目:MsSql
下一篇:SQL Server日期加減函數DATEDIFF與DATEADD用法分析
本文標題:SQL Server里書簽查找的性能傷害
本文地址:http://mengdiqiu.com.cn/a1/MsSql/10505.html
您可能感興趣的文章
- 01-10SQLServer存儲過程實現單條件分頁
- 01-10SQL Server 2012降級至2008R2的方法
- 01-10SQLServer中防止并發(fā)插入重復數據的方法詳解
- 01-10SQL Server數據庫定時自動備份
- 01-10SQL Server性能調優(yōu)之緩存
- 01-10實現SQL Server 原生數據從XML生成JSON數據的實例代碼
- 01-10Sql Server 死鎖的監(jiān)控分析解決思路
- 01-10SqlServer 在事務中獲得自增ID的實例代碼
- 01-10SqlServer快速檢索某個字段在哪些存儲過程中(sql 語句)
- 01-10SQLServer性能優(yōu)化--間接實現函數索引或者Hash索引


閱讀排行
本欄相關
- 01-10SQLServer存儲過程實現單條件分頁
- 01-10SQLServer中防止并發(fā)插入重復數據的方
- 01-10SQL Server 2012降級至2008R2的方法
- 01-10SQL Server性能調優(yōu)之緩存
- 01-10SQL Server數據庫定時自動備份
- 01-10Sql Server 死鎖的監(jiān)控分析解決思路
- 01-10實現SQL Server 原生數據從XML生成JSON數
- 01-10SqlServer快速檢索某個字段在哪些存儲
- 01-10SqlServer 在事務中獲得自增ID的實例代
- 01-10SQLServer性能優(yōu)化--間接實現函數索引或
隨機閱讀
- 01-10SublimeText編譯C開發(fā)環(huán)境設置
- 01-10delphi制作wav文件的方法
- 08-05DEDE織夢data目錄下的sessions文件夾有什
- 01-10使用C語言求解撲克牌的順子及n個骰子
- 08-05dedecms(織夢)副欄目數量限制代碼修改
- 04-02jquery與jsp,用jquery
- 08-05織夢dedecms什么時候用欄目交叉功能?
- 01-11ajax實現頁面的局部加載
- 01-10C#中split用法實例總結
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文