Postgresql

Postgres分區的幾個問題(分層分區、HASH、PK順序)

  • July 11, 2021

我對 Postgres 和 RDBMS 分區很陌生。關於分區的性能優勢,我有一些相關的問題。

背景:我正在嘗試修復超過 3 億行的 4 列表上的慢速批處理查詢。PK 在所有列上,不在 PK 開頭的 3 列也有單列索引。

索引正在失控地增長,並且總體上大於所有 RAM,並且是基礎數據大小的 3 倍。批處理定期讀取和寫入數億行,而且速度很慢。

我已經完成/理解的內容:我分析了程式碼並確定SELECT WHERE子句中只使用了第一列和最後一列。除了INSERTs 之外,沒有其他查詢命中該表(除了DELETE將替換為分區刪除的 a 之外)。所以我已經知道我可以刪除三個索引中的兩個,因為它們未使用,這將導致索引大小減少,索引更少,並有望提高INSERT/SELECT性能。

除了刪除未使用的索引之外,我將使用分區來替換冗長的DELETE語句(WHERE在中間的兩個列上有一個),而是LIST在這些列上進行分區,以便我可以進行DROP分區。

**我有問題的地方:**我提議LIST的分區也有點破壞了表,所以分區不超過原始表大小的 1/4。然而,即使是那個尺寸也非常大。我正在考慮HASH在第 4 列添加一個帶有分區的第二個分層分區層,這可以進一步顯著減小分區大小。我希望這將進一步減少 RAM 消耗和/或以其他方式提高性能。

但是,我對此有幾個問題:

  1. 雖然我會減少分區大小,但我的查詢實際上選擇了我將使用HASH分區的列中的幾乎每個值。我不知道這些選定值的分佈,所以可能有冷熱分區,但很少有完全冷的分區。在這種情況下,HASH分區甚至會有所幫助,還是對單級分區沒有任何改進?這讓我有點困惑,因為由於散列設計是隨機的,所以我希望這在HASH使用時會成為一個問題。

我認為它可能有幫助的唯一原因是降低索引樹的高度,因為索引存在於分區中。但仍會使用所有索引。基本上我想知道的是,與一個巨大的索引相比,即使可以使用所有索引,降低索引高度是否仍然是一種改進?是否有關於何時HASH可能有幫助的最佳實踐?

  1. 分區層次結構的上層LIST位於兩個中間列上,因為這就是我的DELETE(我要替換的)的定義方式。但是這些列從未在WHERE子句中使用。如果頂級分區層次結構級別甚至沒有在WHERE子句中使用,這是否有問題?我可以顛倒順序,所以它HASH是父分區,因為我實際上是通過它選擇的,但是當我DROP而不是一個父分區時,我需要刪除多個子分區。我應該硬著頭皮換順序嗎?
  2. 分區層次的順序是否最好匹配PK的順序?換句話說,如果我的父分區是LIST(col2, col3),我的子分區是HASH(col4),我應該將我的 PK 從 1,2,3,4 更改為 2,3,4,1 以匹配,還是沒關係?

我在這裡看不到 HASH 分區層的任何意義。您可以將索引樹高度降低一個級別,但只能通過在分區“樹”高度上添加另一個級別,這不會是一個積極的權衡。

如果在插入之前按其未來的散列分區對批量行進行排序,則可以從進行索引維護中受益。但是 PostgreSQL 沒有提供進行這種預排序的工具,甚至沒有提供讓您自己輕鬆進行排序的工具。

事實上,我並沒有真正看到 HASH 分區的意義。我認為最好的情況是當您擁有主表和詳細表時,兩者都由相同的鍵分區,即連接鍵。然後你可以進行分區連接。但這似乎不適用於您。

引用自:https://dba.stackexchange.com/questions/295506