數據庫查詢優化器是否知道儲存性能差異?
據我了解,SQL Server(或任何其他 RDBMS,實際上)中的查詢優化器並不了解數據庫下儲存的性能,並且會做出所有儲存都具有相同成本的決策。這是否準確,或者是否考慮了一些關於儲存性能的知識?
在一個完全人為的範例中,假設我的表行儲存在我的 SAN 中的 SSD 驅動器上,具有瞬時訪問時間,我的索引儲存在極度過載的 SAS 驅動器上,導致磁碟飽和和不斷的磁碟隊列。當 RDBMS 生成執行計劃時,它是否更傾向於表掃描而不是索引操作(或者可能是瘦索引和關聯的表查找,而不是覆蓋索引,因為它在 SAS 磁碟上的 IO 較少)?
我懷疑答案是肯定的“優化器不可能聰明甚至知道磁碟性能”,但我只是想看看那裡是否有人確定。我正在使用 SQL Server,但我對任何數據庫系統都感興趣。
Sql server 的查詢優化器在編譯查詢計劃時不會考慮磁碟性能的變化。Paul White 在這裡對 Sql Server 的基於成本的優化器進行了很好的概述:
https://sqlkiwi.blogspot.com/2010/09/inside-the-optimizer-plan-costing.html
一些關鍵點是:
- 優化器不會嘗試計算計劃的確切成本。它試圖在幾個備選方案中選擇成本相對最低的計劃。
- 這是對現實的簡化視圖。它假設伺服器可以執行 320 io/sec 並且 cpu 性能在十多年來沒有增加。
- 儘管今天的伺服器具有截然不同的性能特徵,但優化器在大多數情況下仍然做得非常好。
那麼,為什麼微軟不向優化器添加一些額外的智能呢?然而,在未來,他們更有可能對單個迭代器的成本進行小幅調整。目前還沒有好處來證明這種努力是合理的。
您可以使用未記錄的 dbcc 呼叫來更改某些查詢優化器假設。不要在生產伺服器上使用這些
DBCC SETIOWEIGHT(<multiplier>) DBCC SETCPUWEIGHT(<multiplier>)
兩者的預設值都是 1。與它們一起玩,看看你是否能想出在大多數情況下始終產生更好計劃的不同值。你會發現小的改變不會改變大多數計劃,而大的改變會產生非常奇怪的計劃。
另外一點是,雖然 SQL 在編譯計劃時不會考慮 io 性能,但它確實會在計劃執行期間響應 io 性能(如果 io 飽和,則限制預讀等)