PostgreSQL 內置分區功能

作者:Rock Zhang

分區是指將一個邏輯上大的表拆分爲較小的物理塊。主分區表不存儲任何數據,數據存儲在各個子分區表中。主表與分區表屬於一對多的關係,這些子表繼承並屬於一個主表。

分區可以提供以下好處:

  • 在某些情況下,尤其是當表中大多數被頻繁訪問的行位於單個分區或少量分區中時,查詢性能可以得到顯着提高。分區減小了索引的大小,並使索引中頻繁使用的部分更有可能裝入內存。

  • 當查詢或更新訪問單個分區的很大一部分時,可以通過對該分區進行順序掃描而不是使用索引和分散在整個表中的隨機訪問讀取來提高性能。

  • 可以通過添加或刪除分區來完成批量加載和刪除。使用ALTER TABLE DETACH PARTITION或DROP TABLE進行刪除單個分區比批量操作要快得多。這些命令還完全避免了由批量DELETE引起的VACUUM開銷。

  • 很少使用的數據可以遷移到更便宜、更慢的存儲介質上。

通常只有在表很大的情況下,這些好處纔是值得的。表可以從分區中受益的確切時間取決於應用程序,儘管經驗法則是表的大小應超過數據庫服務器的物理內存。

PostgreSQL 10 以後的版本爲分區提供內置支持:

1 範圍分區(PARTITION BY RANGE)
該表被劃分爲由鍵列或列集定義的“範圍”,分配給不同分區的值的範圍之間沒有重疊。例如,可以按日期範圍或特定業務對象的標識符範圍進行分區。

2 列表分區(PARTITION BY LIST)
通過顯式列出哪些鍵值出現在每個分區中來對錶進行分區。

列表分區的實例

某系統的一張表含有來自企業內部和企業外部不同數據源的數據,用字段is_inner來標識數據來源,當is_inner=True時,數據來自內部, 反正來自外部。系統更多的情況會對來自內部和外部的數據分別經行管理,將數據集根據來源切分成兩張表可以明顯提高查詢性能,和減少表的維護成本。

  1. 創建分區表(主表), 聲明爲列表分區, 這裏沒有主鍵和索引。

CREATE TABLE IF NOT EXISTS dv (
    id        serial,
    d1        int,
    d2        int,
    d3        int,
    is_inner  bool not null
) PARTITION BY LIST(is_inner);

2 分別創建分區(子表),聲明各自的數據範圍

CREATE TABLE dv_inner PARTITION OF dv
    FOR VALUES IN (True);

CREATE TABLE dv_outer PARTITION OF dv
    FOR VALUES IN (False);

3 爲每個分區(子表)創建索引


CREATE INDEX ON dv_inner (id);
CREATE INDEX ON dv_outer (id);

至此已經完成分區表的創建。

下面插入一些數據並查詢

insert into dv (d1,d2,d3,is_inner) values (1,1,1, True);
insert into dv (d1,d2,d3,is_inner) values (2,2,2, False);

查詢所有分區的數據

select * from dv;

查詢單個分區的數據

select * from dv_inner;
select * from dv_outer;

內置分區的約束

  • 沒有可用於在所有分區上自動創建匹配索引的工具。必須使用單獨的命令將索引添加到每個分區。這也意味着無法創建跨越所有分區的主鍵,唯一約束或排除約束。只能單獨約束每個子分區。

  • 由於分區表不支持主鍵,因此不支持引用分區表的外鍵,也不支持從分區表到其他表的外鍵引用。

  • 將ON CONFLICT子句與分區表一起使用會導致錯誤,因爲唯一約束或排除約束只能在單個分區上創建。不支持在整個分區層次結構中強制執行唯一性(或排除約束)。

  • 導致行從一個分區移動到另一個分區的UPDATE失敗,因爲該行的新值不能滿足原始分區的隱式分區約束。

  • 如果需要,行觸發器必須在單個分區上定義,而不是在分區表上定義。

  • 不允許在同一分區樹中混合臨時和永久關係。因此,如果分區表是永久性的,則分區也必須是永久性的,分區表是臨時的也是如此。使用臨時關係時,分區樹的所有成員必須來自同一會話。
    義。

  • 不允許在同一分區樹中混合臨時和永久關係。因此,如果分區表是永久性的,則分區也必須是永久性的,分區表是臨時的也是如此。使用臨時關係時,分區樹的所有成員必須來自同一會話。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章