Postgres分區的幾個問題(分層分區、HASH、PK順序)
我對 Postgres 和 RDBMS 分區很陌生。關於分區的性能優勢,我有一些相關的問題。
背景:我正在嘗試修復超過 3 億行的 4 列表上的慢速批處理查詢。PK 在所有列上,不在 PK 開頭的 3 列也有單列索引。
索引正在失控地增長,並且總體上大於所有 RAM,並且是基礎數據大小的 3 倍。批處理定期讀取和寫入數億行,而且速度很慢。
我已經完成/理解的內容:我分析了程式碼並確定
SELECT WHERE
子句中只使用了第一列和最後一列。除了INSERT
s 之外,沒有其他查詢命中該表(除了DELETE
將替換為分區刪除的 a 之外)。所以我已經知道我可以刪除三個索引中的兩個,因為它們未使用,這將導致索引大小減少,索引更少,並有望提高INSERT
/SELECT
性能。除了刪除未使用的索引之外,我將使用分區來替換冗長的
DELETE
語句(WHERE
在中間的兩個列上有一個),而是LIST
在這些列上進行分區,以便我可以進行DROP
分區。**我有問題的地方:**我提議
LIST
的分區也有點破壞了表,所以分區不超過原始表大小的 1/4。然而,即使是那個尺寸也非常大。我正在考慮HASH
在第 4 列添加一個帶有分區的第二個分層分區層,這可以進一步顯著減小分區大小。我希望這將進一步減少 RAM 消耗和/或以其他方式提高性能。但是,我對此有幾個問題:
- 雖然我會減少分區大小,但我的查詢實際上選擇了我將使用
HASH
分區的列中的幾乎每個值。我不知道這些選定值的分佈,所以可能有冷熱分區,但很少有完全冷的分區。在這種情況下,HASH
分區甚至會有所幫助,還是對單級分區沒有任何改進?這讓我有點困惑,因為由於散列設計是隨機的,所以我希望這在HASH
使用時會成為一個問題。我認為它可能有幫助的唯一原因是降低索引樹的高度,因為索引存在於分區中。但仍會使用所有索引。基本上我想知道的是,與一個巨大的索引相比,即使可以使用所有索引,降低索引高度是否仍然是一種改進?是否有關於何時
HASH
可能有幫助的最佳實踐?
- 分區層次結構的上層
LIST
位於兩個中間列上,因為這就是我的DELETE
(我要替換的)的定義方式。但是這些列從未在WHERE
子句中使用。如果頂級分區層次結構級別甚至沒有在WHERE
子句中使用,這是否有問題?我可以顛倒順序,所以它HASH
是父分區,因為我實際上是通過它選擇的,但是當我DROP
而不是一個父分區時,我需要刪除多個子分區。我應該硬著頭皮換順序嗎?- 分區層次的順序是否最好匹配PK的順序?換句話說,如果我的父分區是
LIST(col2, col3)
,我的子分區是HASH(col4)
,我應該將我的 PK 從 1,2,3,4 更改為 2,3,4,1 以匹配,還是沒關係?
我在這裡看不到 HASH 分區層的任何意義。您可以將索引樹高度降低一個級別,但只能通過在分區“樹”高度上添加另一個級別,這不會是一個積極的權衡。
如果在插入之前按其未來的散列分區對批量行進行排序,則可以從進行索引維護中受益。但是 PostgreSQL 沒有提供進行這種預排序的工具,甚至沒有提供讓您自己輕鬆進行排序的工具。
事實上,我並沒有真正看到 HASH 分區的意義。我認為最好的情況是當您擁有主表和詳細表時,兩者都由相同的鍵分區,即連接鍵。然後你可以進行分區連接。但這似乎不適用於您。