Postgres 9.1与Mysql 5.6 InnoDB?


69

一个简单的问题-2012年对于要求与ACID兼容的中型/大型数据库,哪个会更好?

我已经阅读了所有有关MySQL和pgSQL的文章(大部分),但其中大多数文章分别与版本4,5.1和7,8有关,并且过时(2008、2009)。现在已经快到2012年了,所以我想我们可以尝试重新审视这个问题。

基本上,我想知道PostgreSQL中是否有任何东西超过了MySQL的易用性,可用性和更大的开发人员/知识基础。

MySQL的查询优化器仍然很愚蠢吗?在非常复杂的查询上它仍然超级慢吗?

打我!:)

PS。而且不要将我发送到Google或Wiki。我正在寻找一些特定的要点而不是概述+我更信任StackOverflow,而不是某些随机页面,其中“聪明的家伙”光芒四射。

附录

项目规模:假设一个订购系统每天每个帐户大约10-100个订单,几千个帐户,最终每个帐户可以有数百到数千个用户。

擅长:适应不断增长的需求和不断变化的需求时,要具有面向未来的灵活性。性能对于降低硬件部门的成本也很重要。熟练劳动力的可用性也是一个因素。

OLTP或OLAP:OLTP


5
您需要更准确,更准确地定义一些内容,以使任何答案都有用。像“更好”和“适度”这样的词。更好地为您的DBA腾出了时间,还是更适合刚参加MySQL考试的新员工?是否适中用于CD收集索引或具有1000万用户的消息传递应用程序?OLTP,OLAP?
ptomli

什么是中型或大型数据库?
Hugues Van Landeghem 2012年

Answers:


57

MySQL的查询优化器仍然很愚蠢吗?在非常复杂的查询上它仍然超级慢吗?

所有查询优化器有时都是愚蠢的。在大多数情况下,PostgreSQL并不那么愚蠢。PostgreSQL的一些较新的SQL功能(窗口功能,带有查询的递归等)非常强大,但是如果您使用的是愚蠢的ORM,则可能无法使用。

项目规模:假设一个订购系统每天每个帐户大约10-100个订单,几千个帐户,最终每个帐户可以有数百到数千个用户。

听起来不那么大-完全在一个大盒子里。

擅长:在不断增长的需求和不断变化的需求方面具有前瞻性和灵活性。

PostgreSQL拥有强大的开发人员团队,并拥有广泛的贡献者社区。发行政策是严格的,仅在关键发行版本中有错误修正。始终跟踪9.1.x的最新版本以获取错误修复。

过去,MySQL对版本号的态度较为宽松。甲骨文负责可能会改变这种情况。我对各种分叉的政策不熟悉。

性能对于降低硬件部门的成本也很重要。

如果在如此大的项目中硬件成为主要组件,我会感到惊讶。

熟练劳动力的可用性也是一个因素。

那是您的关键决定者。如果您有一群经验丰富的Perl + PostgreSQL黑客闲着闲逛,请使用它。如果您的员工知道Lisp和MySQL,请使用它。

OLTP或OLAP:OLTP

PostgreSQL在OLTP上一直很强大。

我个人的观点是PostgreSQL邮件列表中充满礼貌,乐于助人,知识渊博的人。您可以直接与拥有Terabyte数据库的用户和建立代码主要部分的黑客联系。支持的质量确实是极好的。


@Richard还有一点,Postgres更改查询在后台运行
ravi404

78

PostgreSQL在SQL功能方面要先进得多。

MySQL仍然不具备的功能(而PostgreSQL具有):

  • 可延缓的约束

  • 检查约束(MySQL的8.0。16中加入它们,MariaDB的10.2有它们)

  • 完全外部联接
    MySQL默默使用内部联接,并带有一些语法变体:https :
    //rextester.com/ADME43793

  • 横向连接

  • 正则表达式不适用于UTF-8(已与MySQL 8.0修复)

  • 正则表达式不支持替换或子字符串MySQL 8.0引入)

  • 表格功能(select * from my_function()

  • 常用表表达式MySQL 8.0引入)

  • 递归查询MySQL 8.0引入)

  • 可写的CTE

  • 窗口函数MySQL 8.0引入)

  • 基于功能的索引

  • 部分索引

  • 在索引中包含其他列(例如,用于唯一索引)

  • 多栏统计

  • 在事务表上进行全文搜索(MySQL 5.6支持此功能)

  • 交易表上的GIS功能

  • EXCEPT或INTERSECT运算符(MariaDB有它们)

  • 您不能在同一条select语句中两次使用临时表

  • 您不能在子选择中使用要更改的表(更新/删除/插入)

  • 您不能创建使用派生表的视图(自MySQL 8.0起可能)

      create view x as select * from (select * from y);
    
  • 语句级别的读取一致性。需要例如:
    update foo set x = y, y = x
    update foo set a = b, a = a + 100

  • 交易DDL

  • DDL触发器

  • 排除约束

  • 键/值存储

  • 索引完整的JSON文档

  • SQL / JSON路径表达式(自Postgres 12起)

  • 范围类型

  • 数组(包括数组上的索引)

  • 角色(组)来管理用户特权(MariaDB拥有它们MySQL 8.0引入

  • 并行查询(自Postgres 9.6起

  • 并行索引创建(自Postgres 11起)

  • 用户定义的数据类型(包括检查约束)

  • 物化视图

  • 自定义聚合

  • 自定义窗口功能

  • 正确的boolean数据类型
    (将任何可以转换为非零值的表达式作为“ true”都不是正确的布尔类型)

当涉及到Spatial / GIS功能时,带有PostGIS的Postgres也更加强大。是一个很好的比较。

不确定您所谓的“易用性”是什么,但是我不想错过一些现代SQL功能(CTE,窗口函数),它们会为我定义“易用性”。

现在,PostgreSQL并不完美,可能最令人讨厌的事情是,调整繁重的VACUUM进程以实现繁重的写入数据库。


NIce的答案-很高兴看到也保持了这种比较!另一个保持全面最新比较的站点出现在此处-在撰写本文时(2020/03/20),最后更新于2020/03/04)。
Vérace

1
您可能会错过的一个,我很惊讶EXPLAIN (ANALYZE, BUFFERS) <text of SQL query>-PostgreSQL产生的非常出色的输出-尽管8.0.20看起来似乎可以缩小差距!
Vérace

11

除了@a_horse_with_no_name答案外,我想命名一些我在PostgreSQL中非常喜欢的功能:


3
关于Postgres,我最喜欢的事情之一是(在撰写本文时)就分组而言,据我所知,它对SQL标准的实现最为准确。您不能按列分组,除非它们包含在聚合函数或group by子句中,或者在功能上依赖于group by子句中包含的列,因此,如果在group by子句中包括表的主键列,您不必在该表中包括所有其他列。SQL Fiddle上的示例
GarethD

@GarethD WOW!不知道 现在我希望我的下一个工作是PostgreSQL!
罗曼·佩卡

MySQL还允许您执行此操作,但是它也允许您简单地忽略所有无关的列。结果中这些列的值是未定义的,除非您所描述的情况如此(如预期)。
rich remer 2014年

是的-DISTINCT ONGROUP BY没有MySQL的一种MySQL sql_mode = ONLY_FULL_GROUP_BY,但至少dev / dba必须对此进行明确说明。现在,在MySQL中,你可以效仿FIRST_VALUE()-那里甚至不应该有一个选项,GROUP BY没有ONLY_FULL_GROUP_BY-这是它应该(只)有1天的工作方式!
Vérace

2

PostgreSQL是一个更成熟的数据库,它的历史更长,它更符合ANSI SQL,其查询优化器明显更好。MySQL具有不同的存储引擎,例如MyISAM,InnoDB,内存,它们在某种意义上是不兼容的,因为在一个引擎上运行的SQL查询在另一个引擎上执行时可能会产生语法错误。在PostgreSQL中,存储过程更好。


从技术上讲,PostgreSQL的历史悠久,但是自从1995年5月首次发布以来(根据Wikipedia),这似乎并不重要。我不同意PostgreSQL更成熟,这更多是关于不同设计目标的问题。
mc0e 2015年

2
@ mc0e:问题在于某些mysql的原始设计目标忽略了RDMS背后的关键原则。
user1071847 '17
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.