PostgreSQL用CTE語法+繼承實現拆分大表
背景
業務設計初期可能不會考慮到表將來會有多大,或者由於資料日積月累,單表會變得越來越大。
後面在考慮分割槽的話,應該怎麼將單表切換成分割槽表呢?
這裡可以用到PostgreSQL的CTE語法,以及繼承功能,還有內建的分割槽表功能。
例子
具體步驟
1、建立分割槽表
2、建立繼承關係,分割槽表繼承自需要拆分的表
3、用cte轉移資料
4、全部轉移完成後,在事務中切換表名
例子,將tbl_big切換成雜湊分割槽
1、建立被遷移的大表
create table tbl_big (id int primary key, info text, crt_time timestamp);
create index idx_tbl_big on tbl_big (crt_time);
insert into tbl_big select generate_series(1,10000000);
2、建立分割槽表
create table tbl ( like tbl_big including all ) ;
do language plpgsql
$$
declare
parts int := 4;
begin
for i in 0..parts-1 loop
execute format(`create table tbl%s (like tbl including all) inherits (tbl)`, i);
execute format(`alter table tbl%s add constraint ck check(mod(id,%s)=%s)`, i, parts, i);
end loop;
end;
$$
;
create or replace function ins_tbl() returns trigger as
$$
declare
begin
case abs(mod(NEW.id,4))
when 0 then
insert into tbl0 values (NEW.*);
when 1 then
insert into tbl1 values (NEW.*);
when 2 then
insert into tbl2 values (NEW.*);
when 3 then
insert into tbl3 values (NEW.*);
else
return NEW; — 如果是NULL則寫本地父表
end case;
return null;
end;
$$
language plpgsql strict;
create trigger tg1 before insert on tbl for each row when (NEW.id is not null) execute procedure ins_tbl();
3、分割槽表,繼承自被遷移的表
alter table tbl inherit tbl_big;
4、遷移資料
with tmp as (delete from only tbl_big returning ) insert into tbl select from tmp;
— 如果覺得這樣做太久了(一次遷移了所有記錄),可以拆成一個個小任務來做
— 一次遷移10萬條,多次呼叫來完成遷移。
with tmp as (delete from only tbl_big where ctid = any(array(select ctid from only tbl_big limit 100000)) returning ) insert into tbl select from tmp;
5、遷移完成後,切換表名。
postgres=# begin;
postgres=# lock table tbl_big in access exclusive mode ;
postgres=# select count(*) from only tbl_big;
count
0
(1 row)
postgres=# alter table tbl_big rename to tmp_tbl_big;
postgres=# alter table tbl no inherit tmp_tbl_big;
postgres=# alter table tbl rename to tbl_big;
postgres=# end;
參考
《PostgreSQL 傳統 hash 分割槽方法和效能》
《PostgreSQL 10 內建分割槽 vs pg_pathman perf profiling》
《PostgreSQL 10.0 preview 功能增強 – 內建分割槽表》
相關文章
- PostgreSQL用CTE語法+繼承實現平滑拆分大表SQL繼承
- PostgreSQL使用表繼承實現分割槽表SQL繼承
- PostgreSQL 表繼承SQL繼承
- PostgreSQL:表繼承SQL繼承
- PostgreSQL LIST分割槽實現:繼承表+函式+觸發器。SQL繼承函式觸發器
- class語法與繼承繼承
- C語言實現繼承多型C語言繼承多型
- ES6建立類的基本語法和繼承實現原理繼承
- PostgreSQL分割槽表、繼承表記錄去重方法SQL繼承
- PostgreSQL中的繼承SQL繼承
- C語言如何實現繼承及容器C語言繼承
- prototype實現繼承繼承
- 實現JavaScript繼承JavaScript繼承
- python高階語法:繼承性Python繼承
- 繼承的實現方式繼承
- Javascript如何實現繼承JavaScript繼承
- js的繼承實現JS繼承
- PostgreSQL學習手冊(表的繼承和分割槽)SQL繼承
- PostgreSQL DBA(35) - CTESQL
- 實現一個無法被繼承的C++類繼承C++
- ES6實現繼承繼承
- js--如何實現繼承?JS繼承
- JS中繼承的實現JS中繼繼承
- JavaScript實現繼承的方式JavaScript繼承
- es6 class繼承用es5實現繼承
- Javascript實現物件導向繼承JavaScript物件繼承
- C#如何實現多重繼承C#繼承
- 使用Object.create()實現繼承Object繼承
- JSP模板繼承功能實現JS繼承
- odoo 繼承(owl繼承、web繼承、view繼承)Odoo繼承WebView
- CSS樣式表繼承CSS繼承
- MySQL8.0新特性-CTE語法支援MySql
- JS 繼承的 六 種實現方式JS繼承
- js實現繼承的三種方式JS繼承
- 如何用es5實現繼承繼承
- js 原型鏈實現類的繼承JS原型繼承
- JavaScript物件導向—繼承的實現JavaScript物件繼承
- js實現繼承的幾種方式JS繼承