PostgreSQL大表拆分方法

2021-10-06 02:36:24 字數 3191 閱讀 6227

資料庫中單錶如果很大,會帶來很多管理個使用上的不便和問題,因此一般大表都建議進行分割槽,這也是比較常見的將大表拆分的方法,在pg中還可以直接對資料檔案進行操作來實現大表拆分。

例子:

1、建立實驗表,插入資料

這裡需要注意避免使用toast表

bill=

# create table tt1 (c1 int ,c2 int);

create

table

bill=

# insert into tt1 select random()*1000,random()*10000 from generate_series(1,40000000);

insert

040000000

2、檢視當前表對應的資料檔案

這裡面幾個檔案:

bill=

# select pg_relation_filepath('tt1');

pg_relation_filepath

----------------------

base/

16385

/160661

bill=

# vacuum analyze tt1;

vacuum

pg12@test180

-> ls -l 160661

*-rw------- 1 pg12 pg12 1073741824 10月 28 11:26 160661

-rw------- 1 pg12 pg12 376176640 10月 28 11:25 160661.1

-rw------- 1 pg12 pg12 376832 10月 28 11:25 160661_fsm

-rw------- 1 pg12 pg12 49152 10月 28 11:26 160661_vm

3、因為占用了2個檔案,所以我們建立2個目標表,使用繼承關係關聯起來。

bill=

# create table aa (like tt1 including all);

create

table

bill=

# create table aa1 (like aa including all) inherits (aa);

psql: notice: merging column

"c1"

with inherited definition

psql: notice: merging column

"c2"

with inherited definition

create

table

bill=

# create table aa2 (like aa including all) inherits (aa);

psql: notice: merging column

"c1"

with inherited definition

psql: notice: merging column

"c2"

with inherited definition

create

table

4、檢視2個目標表的資料檔案路徑

bill=

# select pg_relation_filepath('aa1');

pg_relation_filepath

----------------------

base/

16385

/160670(1

row)

bill=

# select pg_relation_filepath('aa2');

pg_relation_filepath

----------------------

base/

16385

/160673(1

row)

5、停庫,拷貝資料檔案

pg12@test180-> cp 160661 160670

pg12@test180-> cp 160661.1 160673

6、啟動資料庫,驗證

兩張表加起來剛好4千萬條記錄,完成拆分

bill=

# select count(*) from aa1;

count

----------

29622272(1

row)

bill=

# select count(*) from aa2;

count

----------

10377728(1

row)

7、注意事項

對新錶進行vacuum操作會報錯,原因是新錶的frozenxid比資料檔案中xid還小。

bill=

# vacuum aa1;

psql: error: found xmin 34056674

from before relfrozenxid 34056686

8、修改元資料

bill=

# update pg_class set relfrozenxid='34056674'::xid where relname='aa1';

update

1bill=

# update pg_class set relfrozenxid='34056674'::xid where relname='aa2';

update

1bill=

# vacuum aa1;

vacuum

總結:

雖然這種方法可以實現大表的拆分,但是一般不建議使用。尤其是用到toast儲存時還需要對pg_class中相關的元資料進行修改。對於索引等約束需要進行重建,vm,fsm這些檔案可以直接重建,不影響使用。

億級別大表拆分

筆者是在兩年前接手公司的財務系統的開發和維護工作。在系統移交的初期,筆者和團隊就發現,系統內有一張5000w 的大表。跟蹤 發現,該表是用於儲存資金流水的 關聯著眾多功能點,同時也有眾多的下游系統在使用這張表的資料。進一步的觀察發現,這張表還在以每月600w 的資料持續增長,也就是說,不超過半年,這...

postgresql表分割槽

pg的表分割槽實際就是所說的分表,pg的表分割槽的是採用繼承表的方式。表繼承所有父表的檢查與約束都會被子表繼承,主外來鍵關係不會。乙個子表可以繼承多個父表,修改父表的表結構時,大多數情況下也會修改子表的結構定義。分割槽表就是把邏輯上的乙個大表分割成物理上的幾個小塊。好處 1 delete資料更快,只...

postgresql 外部檔案表

本文主要說明pg中怎麼樣外部檔案轉換為表來使用。這種檔案作為表的存在時寬泛的乙個約束。1.首先掛載庫 2.建立服務 3.可以建立乙個表掛載外部檔案了,外部檔案可以在建立表的時候不存在。4.表建立好後,我們查詢一下。提示 無法開啟檔案,我們此時還沒有建立d txt.txt 檔案,下面我們建立好檔案再次...