PostgreSQL索引和复制技术

时间:2018-01-23 20:19:28

标签: postgresql indexing database-replication

背景:到目前为止,我一直使用Django和它的ORM来构建小型网站,所以哪个数据库(MySQL vs PostgreSQL)正在做窗帘背后的所有工作并不是真正的问题。

最近我决定更多地了解这两者之间的差异。我刚刚读完了这篇(长篇)article,探讨了PostgresSQL中索引是如何工作的,我对以下事实感到非常震惊:

  

“例如,如果我们有一个表上定义了十几个索引,那么只对一个索引覆盖的字段的更新必须传播到所有12个索引中,以反映新行的ctid。”

我根本不是专家,但在更新不涉及索引的字段时,我觉得设计时会发生这样的重载。

此外,本文继续解释PostgreSQL复制策略如何在逻辑级别工作,但在磁盘级别,即主服务器向从服务器发送要应用于磁盘的所有更改的列表(逐字节)而不是更为抽象的指令,如UPDATE <fields> ON <table> WHERE ...

虽然网上比较MySQL和PostgreSQL的很多短文一般都倾向于声称PostgreSQL在技术上更先进(ACID,JSON支持等等),但这两个问题对我来说似乎是一个严重的缺点。您能否确认这些陈述并可能指出有关这些问题的更多资源?

谢谢。

1 个答案:

答案 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语句。这允许更灵活的复制方案。

因此,您所引用的文章在这方面已经过时了。