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