Postgresql

添加 CHECK 約束不會提高 ATTACH PARTITION 在 postgres 表上的性能

  • November 25, 2018

我正在嘗試將表合併到分區中,合併有效,但性能不佳。我讀過這個連結,特別是這個引用….

在執行 ATTACH PARTITION 命令之前,建議在要附加的表上創建一個 CHECK 約束來描述所需的分區約束。這樣,系統將能夠跳過掃描以驗證隱式分區約束。如果沒有這樣的約束,將掃描該表以驗證分區約束,同時在父表上持有 ACCESS EXCLUSIVE 鎖。然後可以在 ATTACH PARTITION 完成後刪除約束,因為它不再需要。

這是我正在使用的 SQL….

ALTER TABLE mess_201811 ADD CONSTRAINT const_201811 CHECK ( loadedtime >=  DATE '2018-11-01' AND loadedtime < DATE '2018-11-23' );
ALTER TABLE mess ATTACH PARTITION mess_201811 FOR VALUES FROM ('2018-11-01') TO ('2018-11-23'); 
ALTER TABLE mess_201811 DROP CONSTRAINT const_201811 ;

盡可能接近我從提到的連結中複製了我的 SQL。這三個命令都可以正常工作,問題是花費的時間。添加約束大約需要 60 秒(公平地說,表中有大約 200 萬條記錄)。但是 ATTACH PARTITION 命令也需要大約 60 秒,這表明我正在第二次掃描表以驗證分區。我的理解是,有了 CHECK 約束,ATTACH 應該是一個簡單的 DDL 語句,並且只需要幾分之一秒。

問題是 ATTACH PARTITION 需要對錶混亂的排他鎖,這會阻止插入記錄 60 秒。

我正在使用 postgres v10.5。餐桌混亂的定義以

PARTITIONED BY loadedtime; 

在我進行測試時,數據庫上沒有其他使用者,也沒有鎖定問題。


在 jjanes 解決方案之後,我檢查了原始文件,引用的範例確實使用了 NOT NULL 欄位約束,儘管它沒有提到這是強制性的。我希望附加約束不會對該表的正常插入產生明顯影響。

如果 mess_201811.loadedtime 可以為空,我只能重現這個,在這種情況下,必須在附加時掃描它的 NULL 值。如果該列不為 NULL,則跳過附件掃描。

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