当需要向具有数百万行的表添加列时,Postgres比MySql更好吗?

And*_*rew 8 mysql postgresql

我们遇到Mysql问题.当我四处搜寻时,我看到很多人遇到同样的问题.

我加入了一个产品,其中数据库有一些表,行数多达1.5亿行.我们的问题的一个例子是这些表中的一个具有超过30列,并且其中大约一半不再使用.当试图删除列或重命名列时,mysql想要复制整个表并重命名.有了这么多的数据,这需要花费很多时间来完成,而且网站几乎一直都处于脱机状态.这只是改进模式的几次大型迁移中的第一次.这些并非常规.我继承了很多清理工作.

我试着去查看人们是否与Postgres有同样的问题,我发现几乎没有什么可以比较这个问题.这是因为Postgres在这方面要好得多,或者只是少用人使用postgres?

Pet*_*aut 18

在PostgreSQL中,向表中添加没有默认值的新列是即时的,因为新列仅在系统目录中注册,而不是实际添加到磁盘上.


Sco*_*owe 11

当你知道的唯一工具是锤子时,你所有的问题看起来都像钉子一样.对于这个问题,PostgreSQL在处理这些类型的更改方面要好得多.事实上,无论你设计应用程序的程度如何,总有一天你必须在实时数据库上更改架构.虽然MySQL的各种引擎在某些极端情况下确实令人惊叹,但这里没有一个有用.PostgreSQL在各个层之间的非常紧密的集成意味着您可以使用事务性ddl之类的东西,它允许您回滚任何不是alter/create database/tablespace的东西.或非常非常快速地改变表格.或者非阻碍创建索引.等等.它将PostgreSQL限制在它做得很好的事情上(传统的事务性数据库负载处理是一个强点),并且在MySQL经常填补空白的事情上并没有那么好,比如使用ndb引擎的实时网络集群存储.

在这种情况下,MySQL中的所有不同引擎都不允许您轻松解决此问题.多个存储引擎的多功能性意味着数据库的词法分析器/解析器/顶层不能像存储引擎那样紧密集成,因此很多很酷的东西pgsql可以在这里做mysql不能.

我的统计数据库中有一个118G的表.它有11亿行.它确实应该被分区,但它并没有被阅读很多,当它是我们可以等待它.在300MB /秒(它所能读取的阵列的速度)上,读取大约需要118*~3秒,或者大约需要5分钟.这台机器有32G的RAM,因此无法将表保存在内存中.

当我在这个表上运行简单语句时:

alter table mytable添加测试文本;

它挂着等待真空.我杀死了真空(选择pg_cancel_backend(12345)(< - pid在那里)并立即完成.此表上的真空需要很长时间才能运行btw.通常这不是什么大问题,但是在更改表结构时,你必须等待真空吸尘器,或杀死它们.

删除列也同样简单快捷.

现在我们来讨论postgresql的问题,那就是堆内MVCC存储.如果添加该列,则执行更新表集test ='abc',它会更新每一行,并使表的大小精确加倍.除非HOT可以更新行,但是你需要一个50%的填充因子表,它是双倍大小的开头.获得空间的唯一方法是等待并让真空随着时间的推移回收它并一次重复使用一次更新,或者运行集群或真空充满将其缩小.

你可以通过一次运行表的某些部分更新(更新pkid在1到10000000之间; ...)并在每次运行之间运行真空来回收空间来解决这个问题.

因此,两个系统都有疣和碰撞来处理.


Ran*_*ndy -4

也许是因为这不应该经常发生。

也许,从字里行间看,您需要向另一个表添加一行,而不是向现有的大型表添加列..?

  • -1,即使在大型表上,能够轻松重构数据库模式也具有巨大的价值。 (3认同)
  • 也许它不应该经常发生,但在极少数必须发生的情况下,它在 mysql 中慢得令人痛苦,而在 pgsql 中却快得令人难以置信。mysql 在许多其他领域获胜,但在需要更改模式等的 24/7 游戏中,pgsql 是明显的赢家。 (2认同)