前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >5. 为什么有时候加字段很快,有时候又很慢?

5. 为什么有时候加字段很快,有时候又很慢?

原创
作者头像
顽石神
发布2022-03-13 22:07:51
2.3K2
发布2022-03-13 22:07:51
举报
文章被收录于专栏:PostgreSQL实战

上一篇中,我们知道postgresql表结构定义存储在系统表pg_attribute中,那么在做表结构变更的时候是否只需要变更系统表就可以了呢?

首先我们构造4000万数据的大表(过程略)来体验PostgreSQL添加字段的速度。

从这里可以看到添加字段只花了7毫秒,对于饱受Mysql做表结构变更困扰的老哥们来说简直不可思议(以前搞Mysql),Mysql 8之后支持通过修改元数据的方式添加索引。

相信到这里,你已经发现PostgreSQL表结构变更实际上是对系统表pg_attribute做插入记录操作,所以速度非常快。

那么,你可能会问,我的生产系统中为什么做表结构更新经常卡住呢?而且有时候耗时非常长。。

接下来我们看一些加字段耗时长的场景:

场景1-字段指定默认值:

示例SQL: alter table xx add column xx varchar(30) default 'xxxx';

这个例子中清楚感觉到加字段使用DEFAULT选项时,对同样数据量的表来说,耗时从7毫秒上升到12分钟,耗时相差1800多倍!

对比加字段前、后记录ctid字段可知,在ADD COLUMN ... DEFAULT ..场景下,除了修改系统表pg_attribute外,还对存储数据行进行内部迁移。

到这里,你可能会说那就通过ctid是否发生变化来判断加字段耗时长短就行,但是凡事总有例外,我们来看一个ctid不变,但是耗时仍然非常长的例子:

场景1-修改字段长度:

示例SQL: alter table xx modify column xx varchar(256) ; pad字符长度从varchar(60)扩大到varchar(256)。

根据刚刚的理论,我们来看看ctid:

下图可以看出变结果变更前后ctid并没有发生变化,那么到底原因是什么呢?

改字段长度前后数据ctid并没有变化,说明表上的数据没有发生变动。 而在改字段过程中硬盘使用率先增加,加完字段之后使用率恢复,说明有临时文件产生。

这里我的理解是PostgreSQL为了安全,在对原表操作前先COPY一份临时数据来预防修改过程中,数据出现异常或者PostgreSQL Crash等场景,保证数据能够回滚。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 场景1-字段指定默认值:
  • 场景1-修改字段长度:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档