Sql-Server

假設 SQL Server 有巨大的記憶體來容納整個數據庫在記憶體中的索引有什麼好處?

  • September 3, 2022

我了解索引查找允許伺服器通過查找索引快速轉到所需的頁面,因此不必將查詢表的所有頁面從磁碟讀取到記憶體中即可獲得好處。

這個問題假設:

  1. 整個數據庫都存在於記憶體中的巨大記憶體,
  2. 被查詢的表沒有索引,
  3. 查詢是從表中選擇數據rate>100
  4. 帶有上述 WHERE 子句的第一個查詢將執行掃描以將整個表的數據頁從磁碟拉入記憶體(因為 上沒有索引rate)。

在這種情況下,我的問題是問 - 對於具有相同 WHERE 子句 ( rate>50) 的該表的後續查詢,SQL 引擎將對已駐留在記憶體中的頁面執行表掃描。rate當整個表都位於記憶體中並且不需要訪問磁碟時,在列上是否有索引對第二次查詢有什麼好處?

做更少的工作幾乎總是比做更多的工作更快。

假設基表和索引都完全存在於記憶體中,如果表很大,索引查找將做的工作要少得多。

這項工作主要表現為 CPU 時間和等待記憶體獲取。與大多數持久儲存相比,記憶體速度很快,但與 CPU 相比仍然非常慢。

表掃描將不得不訪問更多的記憶體頁面,並測試更多的行以查看是否rate > x。執行這些比較測試會消耗 CPU。

索引查找將有效地定位第一個匹配行(通過向下導航 b 樹),然後在下一頁指針之後掃描到索引的末尾。它永遠不需要測試單個行來查看是否rate > x。索引的排序保證找到的所有行都將匹配謂詞,而不進行任何值比較。

假設行儲存佈局,基表將具有每 8KB 頁面的最小行數 - 所有行內列都存在於頁面上。

索引可能比基表更密集,因為它只包含索引數據。與基本表的情況相比,每 8KB 頁有更多行,需要更少的頁面訪問。

還有其他考慮因素,例如如何首先定位屬於目標(表或索引)的頁面。對於堆表,這是使用 IAM 頁完成的。索引查找從元數據中定位 b 樹的根,然後如前所述進行導航。這些方法是不同的,但對於完全在記憶體中的情況,兩者之間不太可能有非常可測量的差異。

掃描整個表還需要更多的鎖和頁面鎖存器,消耗 CPU 並可能阻塞並發寫入器。

請記住,索引是按不同方式排序的基礎數據的單獨子集。當基礎數據發生變化時,更有效的搜尋的代價是額外的儲存和索引維護。

如果您擔心特定硬體上的特定情況,請執行基準測試。

完全相同的論點適用,只是所涉及的速度要高得多。數據仍然必須從記憶體移動到 CPU 記憶體和寄存器。必須移動的數據越少,它完成的就越快。索引會消除此移動中的數據。

以前,磁碟到記憶體的速度是限制因素。相比之下,CPU 的記憶體微不足道。現在磁碟讀取已被消除,讀取 RAM 是限制因素。索引可以幫助解決這個問題。

引用自:https://dba.stackexchange.com/questions/316327