背景:到目前为止,我一直使用Django和它的ORM来构建小型网站,所以哪个数据库(MySQL vs PostgreSQL)正在做窗帘背后的所有工作并不是真正的问题。
最近我决定更多地了解这两者之间的差异。我刚刚读完了这篇(长篇)article,探讨了PostgresSQL中索引是如何工作的,我对以下事实感到非常震惊:
“例如,如果我们有一个表上定义了十几个索引,那么只对一个索引覆盖的字段的更新必须传播到所有12个索引中,以反映新行的ctid。”
我根本不是专家,但在更新不涉及索引的字段时,我觉得设计时会发生这样的重载。
此外,本文继续解释PostgreSQL复制策略如何在逻辑级别工作,但在磁盘级别,即主服务器向从服务器发送要应用于磁盘的所有更改的列表(逐字节)而不是更为抽象的指令,如UPDATE <fields> ON <table> WHERE ...
。
虽然网上比较MySQL和PostgreSQL的很多短文一般都倾向于声称PostgreSQL在技术上更先进(ACID,JSON支持等等),但这两个问题对我来说似乎是一个严重的缺点。您能否确认这些陈述并可能指出有关这些问题的更多资源?
谢谢。
答案 0 :(得分:1)
当一行更新时,PostgreSQL必须在索引上做更多的工作。这是因为表中的UPDATE
actually creates a new row version和索引必须指向新的行版本。
然而,有一种方法可以减轻影响:如果将fillfactor
设置为小于100,那么数据页中有可用空间,并且没有更新索引列,PostgreSQL可以创建一个“heap only tuple”,此类 HOT更新不需要触及任何索引。
MySQL的InnoDB及其secondary indexes (that reference the primary key index)必须减少更新索引的工作量。您需要为每次索引扫描支付费用:首先,您必须扫描辅助索引以查找主键,然后您必须扫描主键索引以查找表行。
所以有一个权衡,但我认为无条件地说一个解决方案更好是片面的。
MySQL比PostgreSQL早得多了一个复制解决方案。它使用二进制日志进行复制,这是一个有点欺骗性的名称,因为它实际上包含SQL语句。
PostgreSQL 9.0版引入了流复制,它将事务日志发送到备用数据库。此信息在物理级别上,因此主数据库和备用数据库在物理上保持一致。这通常比运送SQL语句(索引更新!)更浪费,但它是一个非常稳定的解决方案,不会留下复制冲突的空间。
PostgreSQL v10引入了逻辑复制,它生成了对更改的抽象描述,类似于SQL语句。这允许更灵活的复制方案。
因此,您所引用的文章在这方面已经过时了。