V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
mygreens
V2EX  ›  数据库

Oracle 相比 mysql 的优势在哪里

  •  
  •   mygreens · 2021-04-27 17:32:47 +08:00 · 14424 次点击
    这是一个创建于 1307 天前的主题,其中的信息可能已经有所发展或是发生改变。

    目前的项目用的 mysql,支撑几十亿数据没问题(分库分表),偶尔慢 sql 也能优化索引解决,至于复杂查询通过搜索引擎实现,听说 Oracle 超级贵,那 Oracle 具体有什么优势呢,哪些场景下是 oracle only 的?

    第 1 条附言  ·  2021-04-27 21:51:44 +08:00
    看完了回复,oracle 能单表支撑几十亿数据还是很强的,因为目前因为分表键导致很多需求无法实现,只能同步一个表用另一个分表键。


    我再问下,如果是同时涉及几十个字段的复杂搜索,oracle 可以支持吗,目前用的搜索引擎实现也非常贵。
    第 2 条附言  ·  2021-04-27 22:07:19 +08:00
    有一说一,单表支撑几十亿数据,听着有点玄乎,真的假的啊
    119 条回复    2021-04-30 15:11:37 +08:00
    1  2  
    Navee
        101
    Navee  
       2021-04-29 09:07:33 +08:00
    上周我司 oracle 挂了,看来是钱没给够
    no1xsyzy
        102
    no1xsyzy  
       2021-04-29 09:33:58 +08:00
    @Rocketer 显然是你跑题了……
    主题的核心在于,SQL 是一个**声明式**语言,也就是说它的性能实际上非常依赖具体的编译器(这里是 SQL 语句 -> 执行计划)实现上的优化。那么指出 5.7 vs 8.0 显然是没有跑题。

    顺便,例子:
    SELECT CASE WHEN EXISTS (
    SELECT 1 / 0 FROM dual
    ) THEN 1 ELSE 0 END
    FROM dual

    若干年前文章里看到的时候试了下,MySQL 报除零错;而 Oracle 不报错,因为会报错的语句被整个优化掉了。
    no1xsyzy
        103
    no1xsyzy  
       2021-04-29 09:38:40 +08:00
    @holyzhou 感觉你最开头是误读了,游艇有游艇的必要性。
    如果你只是想跑江里钓个鱼,显然用航空母舰没什么必要;纸船(指 SQLite )也有纸船的价值,甚至(不是数据库隐喻也一样)地球上所有种类的船里,纸船算最多了
    l00t
        104
    l00t  
       2021-04-29 10:50:48 +08:00
    @dynastysea 你这段说得就没几句对的…… Oracle 容忍度高?你写个无索引的,该慢还是慢,还能突破科学规律不成。
    互联网有个毛的 sql 素质啊。互联网就没几个能写像样的 sql 的,sql 稍微长那么一点都看不懂,随便一点业务逻辑就要拿出来在应用代码里解决。数据库弱到不能处理复杂 sql,从业人员也没受到过写复杂 sql 的训练,天天写一些最简单的单表 CRUD 叫高的 sql 素质吗?
    kiddult
        105
    kiddult  
       2021-04-29 11:00:17 +08:00
    @Rocketer 技术总监不省钱。。。。这个确实,不过你们找个老手就够了,过亿数据很少的,这点都用开源搞不定,开发也是够坑
    kiddult
        106
    kiddult  
       2021-04-29 11:03:03 +08:00
    @l00t 他说的比较冲,不过点子点到了,互联网系统除非脑抽,不然绝对禁止复杂 SQL,给后面人维护埋坑的概率太大了。剩下老手踩完坑,基本上写复杂 SQL 的就是没有被现实吊打过的新手或者传统 IT 转过来的了
    l00t
        107
    l00t  
       2021-04-29 11:12:26 +08:00
    @kiddult 每个语言都只用最简单的部分,埋坑概率当然小了。就比如写 shell 脚本,只写一行执行一个命令的,不用管道,也没条件分支,那能有几个坑。但这叫比较高的 shell code 素质么…… 这根本就体现不了啊,纯 shell 新手都能写。
    dynastysea
        108
    dynastysea  
       2021-04-29 11:29:18 +08:00
    @l00t 你这就是杠精了,你没加索引,数据库内部不会给你处理吗?难道你不加数据库就傻叉的全按照无索引逻辑给你处理?知不知道现在机器学习也在数据库应用?你写不出像样的 sql 不代表没有,你去大公司看看吧,有很多都是配套专业的 dba 审查 sql 的。你自己天天写 crud 并不代表所有人都是 crud,你说的 crud 很多更说明了 oracle 没鸟用。
    l00t
        109
    l00t  
       2021-04-29 12:10:47 +08:00
    @dynastysea 不懂还瞎逼逼。你倒是说说数据库内部怎么给你处理啊。
    Rocketer
        110
    Rocketer  
       2021-04-29 12:19:46 +08:00 via iPhone
    @kiddult 原来是字节的高手,难怪一亿数据看不到眼里呢。

    不过我在那个公司的时候,还没有字节,那会儿的软硬件比现在整体落后很多。一些现在免费的特性,当时还是商业软件的卖点。

    再就是,电商的数据对一致性要求较高,比新闻类的应用确实更费资源。不过我具体也理解不深,毕竟我是做中前端的,这么靠后的东西是 C++团队负责的。
    opengps
        111
    opengps  
       2021-04-29 12:37:44 +08:00
    单表支撑几十亿不算问题,毕竟这跟存储的合理性有直接关系,我认为不管是 Oracle 、Sql Server 、Mysql 都可以做到。我实际使用 SqlServer 达到过线上 15 亿,虽然后来换了数据库,但是并不是因为这个地方受阻碍换掉的
    bthulu
        112
    bthulu  
       2021-04-29 12:48:56 +08:00
    流式查询几亿数据的表, 查到一半不想查了, mysql 除了 kill 掉这个查询, 其余无论使用任何方式关闭连接都会持续读完表数据为止才能关掉, 这可能耗时几个小时到几天不等. 而 oracle 能瞬时关掉.
    akira
        113
    akira  
       2021-04-29 12:55:13 +08:00   ❤️ 1
    朋友公司以前是用的 oracle,
    出了问题可以找甲骨文的工程师过来帮忙优化解决
    一个月好像是十来万的费用吧
    xtf2009
        114
    xtf2009  
       2021-04-29 13:33:15 +08:00
    @rekulas 两个库的 DDL 是完全一样的(我们用 flyway 做 DB 版本控制的),服务器和本地机都是机械硬盘,本地机 cpu 单核性能比服务器略快,但是肯定不至于有数量级差距。
    主要是执行计划完全不一样,具体已经记不清,印象里 8.0 的执行计划里取出来的行数比 5.7 少很多很多,考虑到 8.0 重写了 sql 解析器,应该是对 sql 进行了优化。
    dynastysea
        115
    dynastysea  
       2021-04-29 13:56:59 +08:00
    @l00t 呵呵,自己不懂还见不惯别人说,都告诉你了,机器学习,你是瞎子吗?不过以你这个理解程度,告诉你了你都搞不懂,臭 sb,不会好好说话
    dynastysea
        116
    dynastysea  
       2021-04-29 14:38:49 +08:00
    @l00t 鉴于太高端的你也看不懂,我举个比较通俗易懂的例子给你看吧。比如前端需要一个查询,本来是要到数据库底层查询的,但是你考虑到在这个场景下可能会是一个高频的操作,所以经过一些决策,在查询后你就把数据决定缓存下来,就可以加快查找速度了。这个场景你作为前端需要告诉用户要加索引缓存吗?不需要,数据库类似,可以做一些预测,根据当前的状况,尽可能的提高用户的查询。如果你这还看不懂的话就没必要和我沟通了
    maclean
        117
    maclean  
       2021-04-29 17:18:06 +08:00
    oracle 的优化器 CBO optimizer 目前应该是所有 RDBMS 里最复杂的(不说是最先进的)。MYSQL 至少在优化器上还处于比较初级的阶段,虽然 MySQL 的目标可能并不希望实现非常复杂的优化器算法。

    举一个例子, 都不使用索引的情况下,NO INDEX ! NO INDEX | NO INDEX !

    以下数据量是一样的,机器是同一台。 Oracle 11.2.0.4 MySQL 8.0.14

    都没有索引的情况下:oracle 使用 0.04 秒, MySQL 等了 10 分钟也没运行完

    对于简单的 SQL 而言,差别不会有那么大。对于复杂的 SQL 而言, 能明显体现出优化器的优势。

    对于拔高某个技术,没有兴趣。 所以 MYSQL 死忠请勿拍。


    Oracle :

    SQL> set timing on;
    SQL> SELECT c.cust_city,
    2 t.calendar_quarter_desc,
    3 SUM(s.amount_sold) sales_amount
    4 FROM sh.sales s, sh.times t, sh.customers c, sh.channels ch
    5 WHERE s.time_id = t.time_id
    6 AND s.cust_id = c.cust_id
    7 AND s.channel_id = ch.channel_id
    8 AND c.cust_state_province = 'FL'
    9 AND ch.channel_desc = 'Direct Sales'
    10 AND t.calendar_quarter_desc IN ('2000-01', '2000-02','1999-12')
    11 GROUP BY c.cust_city, t.calendar_quarter_desc;

    CUST_CITY CALENDA SALES_AMOUNT
    ------------------------------ ------- ------------
    Cypress Gardens 2000-01 3545.82
    Candler 2000-01 4166.32
    Sanibel 2000-02 17908.67
    Ocala 2000-02 7081.73
    Molino 2000-01 18765.25
    Ocala 2000-01 7146.73
    Palmdale 2000-02 25829.24
    Palmdale 2000-01 37793.44
    Molino 2000-02 17144.7
    Saint Marks 2000-01 55781.37
    Noma 2000-01 33572.55
    Evinston 2000-02 62657.21
    Candler 2000-02 6493.94
    Winter Springs 2000-02 20
    Sugarloaf Key 2000-01 12027.66
    Saint Marks 2000-02 48858.7
    Blountstown 2000-02 38052.58
    Sugarloaf Key 2000-02 9659.44
    Cypress Gardens 2000-02 4928.93
    Evinston 2000-01 53509.69
    Blountstown 2000-01 27024.7
    Sanibel 2000-01 15870.34
    Winter Springs 2000-01 31.46
    Noma 2000-02 23903.58

    已选择 24 行。

    已用时间: 00: 00: 00.04

    执行计划
    ----------------------------------------------------------
    Plan hash value: 1865285285

    ------------------------------------------------------------------------------------------------------------
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
    ------------------------------------------------------------------------------------------------------------
    | 0 | SELECT STATEMENT | | 607 | 46132 | 955 (2)| 00:00:12 | | |
    | 1 | HASH GROUP BY | | 607 | 46132 | 955 (2)| 00:00:12 | | |
    |* 2 | HASH JOIN | | 2337 | 173K| 954 (2)| 00:00:12 | | |
    | 3 | PART JOIN FILTER CREATE | :BF0000 | 274 | 4384 | 18 (0)| 00:00:01 | | |
    |* 4 | TABLE ACCESS FULL | TIMES | 274 | 4384 | 18 (0)| 00:00:01 | | |
    |* 5 | HASH JOIN | | 12456 | 729K| 936 (2)| 00:00:12 | | |
    | 6 | MERGE JOIN CARTESIAN | | 383 | 14937 | 408 (1)| 00:00:05 | | |
    |* 7 | TABLE ACCESS FULL | CHANNELS | 1 | 13 | 3 (0)| 00:00:01 | | |
    | 8 | BUFFER SORT | | 383 | 9958 | 405 (1)| 00:00:05 | | |
    |* 9 | TABLE ACCESS FULL | CUSTOMERS | 383 | 9958 | 405 (1)| 00:00:05 | | |
    | 10 | PARTITION RANGE JOIN-FILTER| | 918K| 18M| 526 (2)| 00:00:07 |:BF0000|:BF0000|
    | 11 | TABLE ACCESS FULL | SALES | 918K| 18M| 526 (2)| 00:00:07 |:BF0000|:BF0000|
    ------------------------------------------------------------------------------------------------------------

    Predicate Information (identified by operation id):
    ---------------------------------------------------

    2 - access("S"."TIME_ID"="T"."TIME_ID")
    4 - filter("T"."CALENDAR_QUARTER_DESC"='1999-12' OR "T"."CALENDAR_QUARTER_DESC"='2000-01' OR
    "T"."CALENDAR_QUARTER_DESC"='2000-02')
    5 - access("S"."CUST_ID"="C"."CUST_ID" AND "S"."CHANNEL_ID"="CH"."CHANNEL_ID")
    7 - filter("CH"."CHANNEL_DESC"='Direct Sales')
    9 - filter("C"."CUST_STATE_PROVINCE"='FL')


    统计信息
    ----------------------------------------------------------
    0 recursive calls
    0 db block gets
    1726 consistent gets
    0 physical reads
    0 redo size
    1495 bytes sent via SQL*Net to client
    531 bytes received via SQL*Net from client
    3 SQL*Net roundtrips to/from client
    1 sorts (memory)
    0 sorts (disk)
    24 rows processed


    SQL> select count(*) from sh.sales;

    COUNT(*)
    ----------
    918843

    SQL> select * From v$VERSION;

    BANNER
    --------------------------------------------------------------------------------
    Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
    PL/SQL Release 11.2.0.4.0 - Production
    CORE 11.2.0.4.0 Production
    TNS for 64-bit Windows: Version 11.2.0.4.0 - Production
    NLSRTL Version 11.2.0.4.0 - Production

    MySQL :

    mysql> SELECT c.cust_city,
    -> t.calendar_quarter_desc,
    -> SUM(s.amount_sold) sales_amount
    -> FROM sh.sales s, sh.times t, sh.customers c, sh.channels ch
    -> WHERE s.time_id = t.time_id
    -> AND s.cust_id = c.cust_id
    -> AND s.channel_id = ch.channel_id
    -> AND c.cust_state_province = 'FL'
    -> AND ch.channel_desc = 'Direct Sales'
    -> AND t.calendar_quarter_desc IN ('2000-01', '2000-02','1999-12')
    -> GROUP BY c.cust_city, t.calendar_quarter_desc;


    +----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+----------------------------------------------------+
    | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
    +----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+----------------------------------------------------+
    | 1 | SIMPLE | ch | NULL | ALL | NULL | NULL | NULL | NULL | 5 | 20.00 | Using where; Using temporary |
    | 1 | SIMPLE | t | NULL | ALL | NULL | NULL | NULL | NULL | 1804 | 30.00 | Using where; Using join buffer (Block Nested Loop) |
    | 1 | SIMPLE | c | NULL | ALL | NULL | NULL | NULL | NULL | 55065 | 10.00 | Using where; Using join buffer (Block Nested Loop) |
    | 1 | SIMPLE | s | NULL | ALL | NULL | NULL | NULL | NULL | 914584 | 0.10 | Using where; Using join buffer (Block Nested Loop) |
    +----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+----------------------------------------------------+



    mysql> select version();
    +-----------+
    | version() |
    +-----------+
    | 8.0.14 |
    +-----------+
    1 row in set (0.00 sec)

    mysql> select count(*) from sh.sales;
    +----------+
    | count(*) |
    +----------+
    | 918843 |
    +----------+
    1 row in set (0.96 sec)
    maclean
        118
    maclean  
       2021-04-29 19:30:53 +08:00
    ps 关于互联网企业是否使用 oracle 。虽然大部分互联网企业的主营业务确实很少有用 oracle , 但并不影响他们也需要使用 ERP HR 等系统,所以还是会有部分 oracle 的。

    互联网公司不使用 oracle 数据库这个印象对很多同学来说是有点深的;为了打破这个错误印象,老刘根据维基百科上的世界上最大的前 20 家互联网公司列表做了梳理, 其中 15 家有使用 oracle 数据库技术占 75%,其中 5 家使用了 Exadata 一体机占 25%,其中 5 家为重度使用占 25%。​​​​比较典型的互联网公司例如 facebook,其实一直在使用 oracle 。Apple 苹果因为不算互联网公司,所以不列在其中,但其也较为重度使用 oracle 。

    TOP INTERNET COMPANIES USERS
    以下排名根据维基百科 List of the largest Internet companies https://en.wikipedia.org/wiki/List_of_largest_Internet_companies

    Amazon 亚马逊 近年对外宣布完全去掉 Oracle RDBMS
    Google 谷歌 有用 ==> 根据报道 Google 之前一直在使用 Oracle 财务软件等企业管理软件(2021-04-06 Google 与 Oracle 的诉讼后有报道准备迁移到 SAP),那么应当配套使用了 Oracle RDBMS
    京东 有用,且用了 Oracle Exadata 一体机
    Facebook 脸书 使用,且用了 Oracle Exadata 一体机
    alibaba 阿里巴巴 早年宣布完全去掉 Oracle RDBMS,但似乎前几年还在用 peoplesoft
    tencent 腾讯 有用,似乎有过一套 8 节点 RAC
    苏宁 suning.com 不清楚,似乎主要用 ibm 的技术
    tesla 特斯拉 有用,和 oracle 关系不错
    netflix 重度使用,且用了 Oracle Exadata 一体机
    字节跳动 bytedance 不清楚 ,似乎完全没用
    paypal 重度使用,且用了 Oracle Exadata 一体机
    SalesForce 重度使用
    百度 baidu 有少量使用,有多台 Exadata
    booking.com 有用
    uber 有用
    美团点评 有少量使用
    Expedia 有用
    Rakuten 乐天 重度使用,且用了 Oracle Exadata 一体机
    Adobe 有用
    Ebay 重度使用,且用了 Oracle Exadata 一体机
    zlowly
        119
    zlowly  
       2021-04-30 15:11:37 +08:00
    我看了看手头上某台小型机里的某业务 oracle 数据库,上亿记录的表几十个吧,超 10 亿的表不多才 5 个,最大一个 60 亿记录。根据业务量推算上级地区部门的数据库的这部分业务数据应该是我们 4 倍的数据量。
    1  2  
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5603 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 08:07 · PVG 16:07 · LAX 00:07 · JFK 03:07
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.