PostgreSQL字符類型長度變更的性能


PostgreSQL字符類型長度變更的性能

背景

業務有時會遇到表中的字符型字段的長度不夠用的問題,需要修改表定義。但是表里的數據已經很多了,修改字段長度會不會造成應用堵塞呢?

測試驗證

做了個小測試,如下

建表並插入1000w數據

postgres=# create table tbx1(id int,c1 char(10),c2 varchar(10));
CREATE TABLE
postgres=# insert into tbx1 select id ,'aaaaa','aaaaa' from generate_series(1,10000000) id;
INSERT 0 10000000 

變更varchar類型長度
postgres=# alter table tbx1 alter COLUMN c2 type varchar(100);
ALTER TABLE
Time: 1.873 ms
postgres=# alter table tbx1 alter COLUMN c2 type varchar(99);
ALTER TABLE
Time: 12815.678 ms
postgres=# alter table tbx1 alter COLUMN c2 type varchar(4);
ERROR:  value too long for type character varying(4)
Time: 5.328 ms 

變更char類型長度

postgres=# alter table tbx1 alter COLUMN c1 type char(100);
ALTER TABLE
Time: 35429.282 ms
postgres=# alter table tbx1 alter COLUMN c1 type char(6);
ALTER TABLE
Time: 20004.198 ms
postgres=# alter table tbx1 alter COLUMN c1 type char(4);
ERROR:  value too long for type character(4)
Time: 4.671 ms 

變更char類型,varchar和text類型互轉

alter table tbx1 alter COLUMN c1 type varchar(6);
ALTER TABLE
Time: 18880.369 ms
postgres=# alter table tbx1 alter COLUMN c1 type text;
ALTER TABLE
Time: 12.691 ms
postgres=# alter table tbx1 alter COLUMN c1 type varchar(20);
ALTER TABLE
Time: 32846.016 ms
postgres=# alter table tbx1 alter COLUMN c1 type char(20);
ALTER TABLE
Time: 39796.784 ms
postgres=# alter table tbx1 alter COLUMN c1 type text;
ALTER TABLE
Time: 32091.025 ms
postgres=# alter table tbx1 alter COLUMN c1 type char(20);
ALTER TABLE
Time: 26031.344 ms 

 

定義變更后的數據

定義變更后,數據位置未變,即沒有產生新的tuple

 

postgres=# select ctid,id from tbx1 limit 5;
 ctid  | id 
-------+----
 (0,1) |  1
 (0,2) |  2
 (0,3) |  3
 (0,4) |  4
 (0,5) |  5
(5 rows) 

除varchar擴容以外的定義變更,每個tuple產生一條WAL記錄
$ pg_xlogdump -f -s 3/BE002088 -n 5
rmgr: Heap        len (rec/tot):      3/   181, tx:       1733, lsn: 3/BE002088, prev 3/BE001FB8, desc: INSERT off 38, blkref #0: rel 1663/13269/16823 blk 58358
rmgr: Heap        len (rec/tot):      3/   181, tx:       1733, lsn: 3/BE002140, prev 3/BE002088, desc: INSERT off 39, blkref #0: rel 1663/13269/16823 blk 58358
rmgr: Heap        len (rec/tot):      3/   181, tx:       1733, lsn: 3/BE0021F8, prev 3/BE002140, desc: INSERT off 40, blkref #0: rel 1663/13269/16823 blk 58358
rmgr: Heap        len (rec/tot):      3/   181, tx:       1733, lsn: 3/BE0022B0, prev 3/BE0021F8, desc: INSERT off 41, blkref #0: rel 1663/13269/16823 blk 58358
rmgr: Heap        len (rec/tot):      3/   181, tx:       1733, lsn: 3/BE002368, prev 3/BE0022B0, desc: INSERT off 42, blkref #0: rel 1663/13269/16823 blk 58358 

 

結論

  1. varchar擴容,varchar轉text只需修改元數據,毫秒完成。
  2. 其它轉換需要的時間和數據量有關,1000w數據10~40秒,但是不改變數據文件,只是做檢查。
  3. 縮容時如果定義長度不夠容納現有數據報錯
  4. 不建議使用char類型,除了埋坑幾乎沒什么用,這一條不僅適用與PG,所有關系數據庫應該都適用。

文章來源:https://yq.aliyun.com/articles/463914

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM