PostgreSQL 14新特性--減少索引膨脹
PG12中索引的存儲更加高效,PG13添加索引條目去重功能進一步提升存儲效率。PG14將帶來“自底向上”的索引條目去除功能,旨在減少不必要的頁面分裂、索引膨脹和更新大量索引帶來的碎片。
為什么會出現索引膨脹
對于B-tree索引,表中每個行版本都有一個未死的索引條目(對所有人可見)。執行vacuum刪除死記錄時,也會刪除對應的索引條目。和表一樣,同樣會在索引頁中創建空的空間。這樣的空間可以重用,但是如果沒有新元組插入該頁,這樣的空間會保持為空。
這種膨脹在某種程度上是不可避免的,也是正常的。但如果膨脹太多,索引效率就會降低:
1) 對于索引范圍掃描,必須掃描更多的頁
2) RAM中緩存了索引頁,意味著緩沖膨脹,就是浪費了RAM
3) 每個頁中更少的索引條目意味著更少的“fan out”,索引樹的層級將更高
如果頻繁更新相同行,就會發生這種情況。VACUUM清理老元組前,表和索引會維護相同行的很多版本。如果索引頁填滿,將令人很煩:然后PG會將索引頁分裂成2個。這是一個昂貴的操作,VACUUM執行完清理,我們最終會得到2個臃腫的頁面而不是一個。
當前用于改善索引膨脹和性能的特性HOT元組
HOT元組的創建可能是PG對抗索引中不必要條目的強大武器。使用此功能UPDATE創建產生的元組不會被索引條目引用,它還會引用元組的老版本。通過這種方法,不需要創建新的索引條目,可以避免索引膨脹。
殺死索引條目
當索引掃描遇到一個指向死元組的條目時,標記該條目“killed”。后續索引掃描會在VACUUM刪除他們之前跳過這些條目。此外,PG可以在索引頁面已滿時刪除這樣的條目,以避免頁分裂。
PG14如何進一步減少索引膨脹
自下而上的索引元組刪除比之前方法更進一步:他在索引頁分裂即將發生前就刪除指向死元組的索引條目。這可以減少索引條目的數量并避免昂貴的分裂,以及稍后VACUUM清理參數的膨脹。
在某種程度上,這執行了之前VACUUM的部分公眾,在這點上可以避免索引膨脹。
案例
為了演示新功能效果,使用pgbench分別在PG13和14上執行操作:
測試表:
Pgbench名為bench.sql的腳本:
我運行腳本 60000 次(6 個客戶端 10000 次迭代),如下所示:
pgbench -n -c 6 -f bench.sql -t 10000 test
比較測試結果
我們使用pgstattuple擴展來獲取psql 的索引統計信息:
這是我們在 v13 中得到的:
對于 v14,結果是:
改進最大的時testtab_unchanged_idx。在13中,索引膨脹嚴重,而在14中僅有60%的膨脹(這對索引來說還不錯)。在這里我們看到了新功能的最大影響。UPDATE不掃掃描那個索引,因此沒有killed的索引條目,“自底向上的刪除”可以刪除足夠的這樣的條目避免分裂。
也可以衡量testtab_pkey。由于UPDATE掃描該索引,死的索引元組被killed,新特性在分裂前刪除這些元組。與13相比,效果不太明顯,因為13已經很好地避免索引膨脹了。
索引testtab_changed_idx無法從新特性中獲益。因為這進解決了UPDATE不修改索引值的情況。如果想知道為什么testtab_unchanged_idx葉子密度比13低:刪除了索引重復數據。
Pg_upgrade后我們可以使用這項功能嗎?
索引的存儲格式沒有變,所以pg_upgrade PG12及之后版本創建的索引后會自動公眾。但之前版本創建的索引,需要REINDEX后獲益。記住,pg_upgrade僅拷貝索引文件,不會更改內部索引版本。
總結
PG14繼續改進B-tree索引。這個特性雖不是革命性的,但有望為許多公眾負載提供改進的性能,尤其是那些有大量更新的工作負載。
-
存儲
+關注
關注
13文章
4320瀏覽量
85904 -
RAM
+關注
關注
8文章
1368瀏覽量
114752
發布評論請先 登錄
相關推薦
評論