PostgreSQL9.2Beta: 字段类型转换依然需要 rewrite 表

PostgreSQL9.2 对于”ALTER TABLE “ 字段扩长已有很多场景不需要重写表了,具体可以对照之前的 BLOG: https://postgres.fun/20120523180504.html

PostgreSQL9.2Beta 类型转换时是否需要 rewrite 表。

测试场景一: float –> integer

创建测试表并导入数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
francs=> create table test_4 (id float8,name varchar(32));  
CREATE TABLE
francs=> insert into test_4 select generate_series(1,3000000),'a';
INSERT 0 3000000

francs=> select * from test_4 order by id desc limit 5;
id | name
---------+------
3000000 | a
2999999 | a
2999998 | a
2999997 | a
2999996 | a
(5 rows)

francs=> /dt+ test_4
List of relations
Schema | Name | Type | Owner | Size | Description
--------+--------+-------+--------+--------+-------------
francs | test_4 | table | francs | 115 MB |
(1 row)

francs=> timing
Timing is on.

francs=> /d test_4
Table "francs.test_4"
Column | Type | Modifiers
--------+-----------------------+-----------
id | double precision |
name | character varying(32) |

修改字段类型

1
2
3
4
5
6
7
8
9
10
francs=> alter table test_4 alter column id type integer ;  
ALTER TABLE
Time: 23805.774 ms

francs=> /d test_4
Table "francs.test_4"
Column | Type | Modifiers
--------+-----------------------+-----------
id | integer |
name | character varying(32) |

备注: 由 float8 转换成 integer 类型花费了 23 秒,显然重写表了。

测试场景二: integer –> text

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
francs=> /d test_4  
Table "francs.test_4"
Column | Type | Modifiers
--------+-----------------------+-----------
id | integer |
name | character varying(32) |

francs=> alter table test_4 alter column id type text;
ALTER TABLE
Time: 31735.712 ms

francs=> /d test_4
Table "francs.test_4"
Column | Type | Modifiers
--------+-----------------------+-----------
id | text |
name | character varying(32) |

备注: integer 类型转换成 text 类型花费了 31 秒左右,显然重写表了。

测试场景三: text –> integer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
francs=> /d test_4;  
Table "francs.test_4"
Column | Type | Modifiers
--------+-----------------------+-----------
id | text |
name | character varying(32) |

francs=> alter table test_4 alter column id type integer using (id::integer);
ALTER TABLE
Time: 34431.975 ms

francs=> /d test_4
Table "francs.test_4"
Column | Type | Modifiers
--------+-----------------------+-----------
id | integer |
name | character varying(32) |

备注:text 转换成 integer 时,重写了表。

总结

对于字段类型转换例如( float –> integer,integer –> text, text –> integer ) 会发生重写表,更进一步发现表的 pg_class.relfilenode 发生了变化,推测字段类型转换(不是字段扩长)都要 rewrite 表,因为涉及到字段类型转换时需要检测每条记录是否合法,这里只是推测,需要进一步验证。

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/tech/database/237855.html

(0)
上一篇 2022年1月29日 22:29
下一篇 2022年1月29日 22:29

相关推荐

发表回复

登录后才能评论