索引是否應該自動放入它們自己的緩衝池中?
我們使用在 AIX 上執行的 DB2 LUW(具體來說,我們目前使用的是 9.7 FP4)。
根據 IBM 的最佳實踐,他們建議在建構表時,將數據、索引和 LOB/LONG 數據分別放入各自的表空間中。(原因是更好地控制磁碟、維護、備份等)
表空間必須與緩衝池相關聯。現在我們的大多數表和索引都適合 4K 緩衝池和表空間。
通常使用我們的腳本,我們會設置一個 4K 緩衝池 BP4K。然後我們設置至少兩個 4K 表空間(因為我們沒有很多 LOB):用於數據的 TS_DAT_4K 和用於索引的 TS_IND_4K。預設情況下,我們剛剛將這兩個表空間分配給緩衝池 BP4K。
我想知道的是:既然索引在它們自己的表空間中,是否也應該給它們自己的緩衝池?
我想知道這一點的原因是基於優化。如果索引有自己的緩衝池,那麼它們更有可能保留在記憶體中(而不是因為讀入表記錄而被擠出記憶體)。這將允許更快地掃描索引以查找表中的記錄。而且由於索引不再與表共享同一個緩衝池,更多的表現在可以保留在記憶體中用於邏輯檢索而不是物理讀取。所以我的想法是,這將減少物理 I/O,從而有助於數據庫的性能/維護。
我也忍不住想知道這是否只是預優化,這在 99% 的情況下都是一件壞事,會引入額外的成本等(特別是因為我們還沒有確定我們需要基於單獨的緩衝池)目前的性能。當然,正在開發的應用程序還沒有投入生產,仍然需要數據庫調整……)
對此有什麼想法?這是最佳實踐嗎?還是只是預先優化和過度思考?
讓我們並行執行兩個假設的數據庫 (
H1
和H2
),緩衝池 ( ) 的 RAM 總量相同R
。
- 讓我們
H1
有一個大小為 的緩衝池R
。- 讓我們
H2
有兩個緩衝池:一個I
用於索引頁的大小,另一個D
用於數據頁的大小。(D+I==R
當然。)問題是:
- 您如何確定正確的值
I
並D
使其H2
表現優於H1
?我的回答是,一般情況下你不能。數據庫引擎
H1
的記憶體優化空間比H2
. 如果一天中有更多的索引頁面會帶來更好的性能,它可以丟棄未使用的數據頁面並擁有“主要是索引頁面”記憶體。如果稍後數據頁變得更熱,它可以驅逐更多的索引頁並擁有“大部分數據頁”記憶體。
H2
不能那樣做。一旦它I
記憶體了頁面價值的索引頁面,它就無法記憶體更多,即使那是現在最好的。由於對 RAM 的次優使用,它被困在那裡。如果最初選擇的/拆分是理想的,並且工作負載非常穩定,那麼唯一的方法
H2
就是執行得一樣好。這肯定會發生,但我敢打賭這不是一個非常常見的數據庫場景。如果這不是您的情況,請考慮與數據和索引頁面之間的記憶體動態分區相同,但由最了解如何優化 I/O 的事物(即數據庫引擎)直接管理。H1``D``I``H1``H2
這並不是說維護不同的緩衝池絕不是一個好主意。
我遇到的在特定記憶體中隔離特定頁面的一種情況是有一個關鍵的“報告”需要始終快速(顯然)執行,並且碰巧使用了一些幾乎從未在其他地方使用過的表。因此,這些頁面不斷被驅逐,並且該“報告”的執行時間因執行而異。將一組特定的表(及其索引)移動到特定的池中刪除了大部分“非確定性”性能部分。
但這對於整個數據庫來說不是最理想的,更像是一個雜物,更接近於 Voodoo 優化 IMO。(這不在 DB2 上,但我相信這在這裡無關緊要。)
所以我的建議是:如果您有 X Gb 的 RAM 可用於記憶體,請使用單個緩衝區,將所有內容放入其中,然後讓數據庫引擎在其中發揮作用。
如果您遇到了似乎從記憶體隔離中受益的極端情況,請嘗試一下,對其進行基準測試,考慮必須為每個記憶體大小維護幻數的成本,然後轉而調整查詢、架構或磁碟佈局:)