分區是否應該提高索引訪問和更新的性能?
我經常聽到對大表進行分區應該顯著提高查詢速度和插入/更新速度,因為索引按比例較小。
我很難理解為什麼會這樣。
根據我的理解,對索引的操作應該很
log(N)
複雜,所以即使我們將一個巨大的表劃分為 100 個較小的項目,我們也只是將一個索引劃分為 100 個較小的項目。如果查詢頻繁訪問整個數據集中的項目,那麼這 100 個索引無論如何都會競爭處理器記憶體,所以我不明白為什麼數據庫會減少訪問磁碟的頻率。
如果我們通常隻請求數據的一部分——例如,如果我們有一個帶有時間戳數據的表並且更經常對最新數據感興趣——那麼我們必須遍歷的 B-tree 節點數將減少 1 或 2 個。但是在未分區的表場景中,B-tree 的最頂層節點無論如何都會被記憶體,因此 B-tree 稍高的事實不應該對性能產生重大影響。
先前場景的變化:如果我們通常訪問與分區鍵在同一“軸”上的數據范圍 - 再次,如果我們有一個按時間戳分區的表並執行日期範圍的報告 - 那麼分區將為數據,從而減少磁碟訪問並提高查詢性能。但我不明白這將如何提高插入/更新性能?為什麼它應該提高不按分區鍵過濾的查詢的性能?
我意識到分區在其他一些情況下很有用(刪除舊數據、與許多使用者爭用鎖、備份、上述集群等) - 但我通常聽說查詢或更新性能也應該提高,因此這個問題。
我最熟悉 PostgreSQL,但我懷疑許多關係數據庫之間的基本概念是相似的。
分區(至少從 SQL Server 的角度來看,但可能適用於大多數RDBMS)並不是用來提高DQL查詢性能的工具。例如,正如您提到的,由於B-Tree 索引的大 O,您的麵包和黃油
SELECT
語句不會看到分區帶來任何有影響的性能提升。相反,它旨在提高DDL和一些DML查詢的性能(主要是減少爭用),以實現更好的數據庫管理。我強烈推薦這篇關於分區的Brent Ozar 文章(Kendra Little 撰寫),她在其中討論了更多的理論實現(而不是技術和特定的 SQL Server 實現)。
它提到的一個關鍵點是分區切換,它是一種在 5 秒內對數據正在滾動的鍵(例如日期欄位)進行分區的方法,它允許您管理舊分區而不會導致鎖定或爭用整個分區桌子。通過將您的表分成多個分區,您可以歸檔最舊的分區,而不會導致表的其餘部分處於活動狀態。
同樣的想法也適用於其他操作,例如索引重建/重組,以及其他索引和表維護,允許您一次只影響某些分區並減少在任何給定時間對錶的整體爭用和鎖定。您可以相應地更智能地管理您的表及其索引。