“警告:操作導致殘留 I/O”與鍵查找
我在 SQL Server 2017 執行計劃中看到了這個警告:
警告:操作導致剩餘 IO
$$ sic $$. 實際讀取的行數為 (3,321,318),但返回的行數為 40。
下面是 SQLSentry PlanExplorer 的一個片段:
為了改程序式碼,我添加了一個非聚集索引,以便 SQL Server 可以獲取相關行。它工作正常,但通常會有太多(大)列包含在索引中。它看起來像這樣:
如果我只添加索引,沒有包含列,它看起來像這樣,如果我強制使用索引:
顯然,SQL Server 認為鍵查找比殘餘 I/O 昂貴得多。我有一個沒有太多測試數據的測試設置(還沒有),但是當程式碼投入生產時,它需要處理更多的數據,所以我相當確定需要某種非聚集索引。
當您在 SSD 上執行時,關鍵查找真的那麼昂貴嗎,我必須創建全脂索引(包含很多包含列)?
執行計劃: https ://www.brentozar.com/pastetheplan/?id=SJtiRte2X它是長儲存過程的一部分。尋找
IX_BatchNo_DeviceNo_CreatedUTC
。
優化器使用的成本模型正是:模型。它在廣泛的工作負載、廣泛的數據庫設計和廣泛的硬體上產生一般良好的結果。
您通常不應假設單個成本估算與特定硬體配置上的執行時性能密切相關。成本計算的重點是允許優化器在相同邏輯操作的候選物理替代方案之間做出有根據的選擇。
當您真正深入了解細節時,熟練的數據庫專業人員(有時間調整重要查詢)通常可以做得更好。就此而言,您可以將優化器的計劃選擇視為一個很好的起點。在大多數情況下,該起點也將是終點,因為找到的解決方案已經足夠好。
根據我的經驗(和意見),SQL Server 查詢優化器的查找成本比我希望的要高。這在很大程度上是隨機物理 I/O 與順序訪問相比比今天的情況更昂貴的時代的遺留問題。
儘管如此,即使在 SSD 上查找也可能很昂貴,或者最終甚至在僅從記憶體中讀取時也是如此。遍歷 b 樹結構不是免費的。顯然,當你做更多的事情時,成本就會增加。
包含的列非常適合讀取繁重的 OLTP 工作負載,其中索引空間使用和更新成本與執行時讀取性能之間的權衡是有意義的。圍繞計劃穩定性還需要權衡取捨。完全覆蓋的索引避免了優化器的成本模型何時可能從一種替代方案轉換到另一種替代方案的問題。
只有您可以決定在您的情況下權衡是否值得。在具有代表性的數據樣本上測試兩種備選方案,並做出明智的選擇。
在您添加的問題評論中:
你是在告訴我 SQL Server 不知道剩餘 IO 的成本嗎?
不,優化器確實考慮了剩餘 I/O 的成本。實際上,就優化器而言,非 SARGable 謂詞在單獨的過濾器中進行評估。在優化後重寫期間,此過濾器作為殘差被推入查找或掃描中。