簡體   English   中英

避免使用檢查約束掃描附加分區

[英]Avoid scan on attach partition with check constraint

我正在 PostgreSQL 11 中將現有表重新創建為分區表。

經過一些研究,我正在使用以下過程來處理它,因此可以在桌子上仍在進行寫入時在線完成:

  1. 在現有表上添加檢查約束,首先作為無效然后驗證
  2. 刪除現有的主鍵
  3. 重命名現有表
  4. 在之前的表名下創建分區表
  5. 將現有表作為分區附加到新分區表

我的期望是最后一步會相對較快,但我真的沒有這個數字。 在我的測試中,大約需要 30 秒。 我想知道我的期望是否不正確,或者我在約束或其他方面做錯了什么。

這是 DDL 的簡化版本。

首先, inserted_at列聲明如下:

inserted_at timestamp without time zone not null

即使在刪除現有查詢和寫入的 PK 之后,我也希望在 ID 上建立索引,因此我創建了一個索引:

create unique index concurrently my_events_temp_id_index on my_events (id);

檢查約束在一個事務中創建:

alter table my_events add constraint my_events_2022_07_events_check
check (inserted_at >= '2018-01-01' and inserted_at < '2022-08-01')
not valid;

在下一個事務中,它被驗證(並且驗證成功):

alter table my_events validate constraint my_events_2022_07_events_check;

然后在創建分區表之前,我刪除現有表的主鍵:

alter table my_events drop constraint my_events_pkey cascade;

最后,在它自己的事務中,創建分區表:

alter table my_events rename to my_events_2022_07;

create table my_events (
  id uuid not null,
  ... other columns,
  inserted_at timestamp without time zone not null,
  primary key (id, inserted_at)
) partition by range (inserted_at);

alter table my_events attach partition my_events_2022_07
for values from ('2018-01-01') to ('2022-08-01');

最后一個事務阻塞了我的測試數據庫中 12M 行的插入並花費了大約 30 秒。

編輯

我想添加它以響應我看到的attach

信息:現有約束隱含表“my_events_2022_07”的分區約束

這讓我覺得我這樣做是對的。

問題不在於檢查約束,而在於主鍵。

如果您使原始唯一索引包含兩列:

create unique index concurrently my_events_temp_id_index on my_events (id,inserted_at);

而且,如果您使新表在這兩列上具有唯一索引而不是主鍵,那么附加幾乎是瞬時的。

這些在我看來像是 PostgreSQL 中不需要的限制,一列上的唯一索引不能用於暗示兩列的唯一性,並且兩列上的唯一索引不能用於暗示主鍵(甚至唯一約束——但只有唯一索引)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM