MySQL不适合去O(Oracle)的原因分析

1 minute read

背景

去O从互联网逐渐蔓延到传统企业,但是MySQL适合传统企业吗?来听听某些传统用户的心声。

某些传统企业也想学互联网去O的思路,复制互联网的去O神话,但是他们自己调研了一下MySQL之后,发现这种想法并不科学。

这些弊端在PostgreSQL中并不存在,还增加了许多特性可以帮助企业降低开发量。这几年PG在国内的应用越来越多,大到BAT、银行、运营商等,小到各个行业的ISV,人才需求旺盛。

MySQL存在的某些缺陷

1. 对子查询的优化表现不佳;

PostgreSQL 优化器对子查询的支持很好,支持固定子查询,提升子查询,条件上推和下推等等。

2. 对复杂查询的处理较弱;

PostgreSQL 对复杂查询处理能力与Oracle类似。

3. 查询优化器不够成熟;

PostgreSQL 查询优化器很成熟,支持query rewrite, hash join, merge join, nestloop join, HINT, 遗传优化, 固化JOIN顺序, seqscan, indexscan, bitmapscan, indexonlyscan, ctidscan, bitmapand, bitmapor, subqueryscan, material, hashagg, groupingagg, sortagg, union, expect, intersect, mergesort, parallel等手段。

4. 审计功能相对较弱;

PostgreSQL 支持DDL,DML审计,支持按用户,按数据库配置审计级别,支持通过HSTORE实行记录级审计。

5. 存储过程与触发器的功能有限;

PostgreSQL 支持plpgsql存储过程语言,与PL/SQL功能高度相似。

PostgreSQL 支持DML+TRUNCATE行、表级触发器,支持before, after触发器,支持延迟触发器。

PostgreSQL 支持DDL事件触发器。

PostgreSQL 支持规则。

PostgreSQL 支持将DDL封装在事务中,支持DDL的回滚操作。

6. 对于时间、日期、间隔等时间类型没有秒以下级别的存储类型;

PostgreSQL 支持timestamptz,timetz,精确到十万分之一秒。

PostgreSQL 支持interval类型表示时间间隔。

7. 可用来编写存储过程、触发器、计划事件以及存储函数的语言功能较弱;

PostgreSQL plpgsql功能与PL/SQL类似,可以用来编写存储过程,函数,触发器,等。

8. 没有基于回滚(roll-back)的恢复功能,只有前滚(roll-forward)的恢复功能;

PostgreSQL 通过HSTORE可以实现重点表的flashback,粒度精确到事务级别。

PostgreSQL 支持前滚的时间点恢复。

9. 数据完整性检查非常薄弱,即使是基本的完整性约束,也往往不能执行;

PostgreSQL 对约束的支持很好,是根据SQL标准来实现的,与Oracle一致。包括外键,CHECK约束,主键,排他约束,等。

10. 优化查询语句执行计划的优化器提示非常少;

PostgreSQL 执行计划的输出粒度分为多个级别

analyze – 执行并输出实际的COST,时间信息

verbose – 输出详细信息

costs – 输出执行树中每个NODE的评估成本

buffers – 输出包括shared buffer, local buffer, temp buffer在内的命中块数,未命中块数

timing – 输出IO时间,CPU时间等

PostgreSQL 还支持DEBUG输出更详细的信息。

11. 只有一种表连接类型:嵌套循环连接(nested-loop),不支持排序-合并连接(sort-merge join)与散列连接(hash join);

PostgreSQL 支持SQL标准的所有连接方式,包括nestloop, hashjoin , merge join在内。

12. 大部分查询只能使用表上的单一索引;在某些情况下,会存在使用多个索引的查询,但是查询优化器通常会低估其成本,它们常常比表扫描还要慢;

PostgreSQL 支持多个索引联合使用,使用bitmapAnd, bitmapOr,自动合并索引。

13. 不支持位图索引(bitmap index).每种存储引擎都支持不同类型的索引.大部分存储引擎都支持B-Tree索引;

PostgreSQL 支持8种索引,包括Btree, hash, gin, gist, sp-gist, brin, rum, bloom。

其中

gin用于多值类型(包括数组、全文检索类型等)。

gin还可用于倒排,多列聚集,一个GIN索引可以支持任意列的组合查询。

hash用于超长字段的索引。

gist, spgist用于异构数据的索引(例如地理位置、图像、基因、化学分子等)。

brin用于线性相关的数据索引,块级索引,非常小,类似Oracle一体机的块级索引。

rum, 相似度索引,用于全文检索类型,支持相似度的查询。

bloom索引,用于多列的布隆过滤。

14. 大部分存储引擎都不支持外键;

PostgreSQL 支持外键。

15. 不支持绑定变量(没有执行计划缓存),执行计划并不是全局共享的,仅仅在连接内部是共享的;

PostgreSQL 支持绑定变量,执行计划缓存。执行计划是会话级别,好处是同一个SQL被高并发调用时,没有Oracle shared_pin的问题。

16. 没有资源控制.一个完全未经授权的用户可以毫不费力地耗尽服务器的所有内存并使其崩溃,或者可以耗尽所有CPU资源;

PostgreSQL 是进程级模型,与Oracle dedicate模式一样。

可以控制会话的work_mem, 临时文件大小,临时文件数量等。

通过cgroup也可以控制单个用户进程的cpu, iops, network, memory等开销。

17. 不支持函数索引,只能在创建基于具体列的索引;

PostgreSQL 支持函数索引。

18. 不支持物化视图;

PostgreSQL 支持物化视图,支持物化视图增量更新。

19. 不支持Sequence;

PostgreSQL 支持序列。支持字段自动填充序列值。

20. 类似于ALTER TABLE或CREATE TABLE一类的操作都是非事务性的.它们会提交未提交的事务,并且不能回滚也不能做灾难恢复;

PostgreSQL 支持DDL封装在事务中,执行DDL不会导致事务自动提交。

21. mysql对于多表连接什么的性能如何?

PostgreSQL 多表连接,会根据连接字段和条件等,自动优化JOIN顺序,自动选择JOIN方法(nestloop,mergejoin or hash join).

22. mysql DDL需要锁表,并重写,例如一个1G的表alter table add column,需要准备好1G的临时空间,数据要从老表导入新表。而且DDL是排它锁,会长时间影响读写操作。

PostgreSQL alter table add column只需要修改元数据,不需要导表,不管多大的表都可以瞬间完成。

补充PostgreSQL的其他特性

1. PostgreSQL 支持单个QUERY使用多CPU并行计算,支持OLTP和OLAP混用。

2. PostgreSQL 语法、数据类型、函数、等一系列功能与Oracle兼容性非常的好。

3. PostgreSQL 支持JSON类型,支持JSON的内部索引,全量索引等。

4. PostgreSQL 支持GIS类型,广泛应用于军用、科研、民用场景。(气象、测绘、地图、宇航局、路径规划、O2O应用等)

5. PostgreSQL 支持OLAP标准的窗口查询、分析函数、多维分析等。

6. PostgreSQL 支持全文检索、模糊查询、正则查询的假设,亿级数据可以毫秒返回。

7. PostgreSQL 支持数组、复合类型、扩展类型等。

8. PostgreSQL 支持图查询、递归查询、流式计算、图像检索、基因数据减少、化学分子检索、地球类型、LTREE类型等等。

9. PostgreSQL 支持通过插件的形式,扩展功能、性能、类型、等等。

还有更多可参考

《数据库选型 - 致 架构师、开发者》

《数据库界的华山论剑 tpc.org》

《PostgreSQL 前世今生》

《PG培训视频》

Flag Counter

digoal’s 大量PostgreSQL文章入口