Sir*_*ion 3 postgresql indexing database-replication
背景:到目前为止,我一直使用 Django 及其 ORM 来构建小型网站,因此哪个数据库(MySQL 与 PostgreSQL)在幕后完成所有工作并不是真正的问题。
最近我决定更多地了解这两者之间的差异。我刚刚读完这篇(长篇)文章,它探讨了索引在 PostgresSQL 中的工作原理,我对以下事实感到非常震惊:
“例如,如果我们有一个定义了十几个索引的表,那么对仅由单个索引覆盖的字段的更新必须传播到所有 12 个索引中,以反映新行的 ctid。”
我根本不是专家,但对我来说听起来很疯狂,在更新不涉及索引的字段时,这种超载应该是设计使然的。
此外,文章继续解释 PostgreSQL 复制策略如何不在逻辑级别工作,而是在磁盘级别工作,即主服务器向从服务器发送所有更改的列表(逐字节)以应用于磁盘而不是更多抽象指令,例如UPDATE <fields> ON <table> WHERE ....
虽然网上很多比较 MySQL 和 PostgreSQL 的短文一般都倾向于声称 PostgreSQL 在技术上更先进(ACID、JSON 支持等),但这两个问题对我来说似乎是严重的缺点。您能否确认这些陈述并可能指出有关这些问题的更多资源?
谢谢你。
当一行被更新时,PostgreSQL 必须在索引上做更多的工作,这当然是正确的。这是因为UPDATE实际上在表中创建了一个新行版本,并且索引必须指向该新行版本。
但是,有一种方法可以减轻这种影响:如果设置fillfactor为小于 100,则数据页中有空闲空间,并且没有索引列更新,PostgreSQL 可以创建“仅堆元组”,诸如一个热更新不需要接触任何指数。
MySQL 的 InnoDB 及其二级索引(引用主键索引)更新索引的工作量较少。每次索引扫描都要为此付出代价:首先,您必须扫描二级索引以找到主键,然后您必须扫描主键索引以找到表行。
所以有一个权衡,但我认为无条件地说一个解决方案更好是片面的。
MySQL 早于 PostgreSQL 就有了复制解决方案。它使用二进制日志进行复制,这是一个稍微具有欺骗性的名称,因为它实际上包含 SQL 语句。
PostgreSQL 9.0 版引入了流式复制,它将事务日志传送到备用数据库。此信息位于物理级别,因此主要和备用在物理上保持相同。这通常比传送 SQL 语句(索引更新!)更浪费,但它是一个非常稳定的解决方案,没有复制冲突的余地。
PostgreSQL v10 引入了逻辑复制,它会生成变化的抽象描述,类似于 SQL 语句。这允许更灵活的复制场景。
所以你引用的文章在这方面已经有些过时了。