• 入微:探究文档中找不到的12c并行索引扫描新特性


    640?wx_fmt=jpeg

    杨廷琨,网名 yangtingkun

    云和恩墨技术总监,Oracle ACE Director,ACOUG 核心专家


    Oracle在12c之前对于索引范围扫描是没有办法并行执行的,从12.1开始,Oracle可以并行的执行索引扫描。


    创建测试环境

    640?wx_fmt=other

    SQL> create table t_para_ind (id number, name varchar2(30), created date);

     

    Table created.

     

    SQL> insert into t_para_ind select id, object_name, created from t_big;

     

    6735106 rows created.

     

    SQL> commit;

     

    Commit complete.

     

    SQL> create index ind_para_created on t_para_ind (created);

     

    Index created.

     

    SQL> select banner from v$version;

     

    BANNER

    --------------------------------------------------------------------------------

    Oracle Database 18c Enterprise Edition Release 18.0.0.0.0 – Production


    强制执行计划采用索引扫描

    640?wx_fmt=other

    SQL> select /*+ index(t) */ count(name) from t_para_ind t where created >= to_date('201701', 'yyyymm');

     

    Elapsed: 00:00:00.61

    640?wx_fmt=png 

     

    设置语句级并行执行

    640?wx_fmt=other

    下面设置语句级并行执行,首先将优化器参数设置为11.2.0.4版本:

    SQL> select /*+ index(t) parallel(2) opt_param('optimizer_features_enable', '11.2.0.4') */ count(name) from t_para_ind t where created >= to_date('201701', 'yyyymm');

     

    Elapsed: 00:00:00.64

    640?wx_fmt=png


    对于11.2.0.4的优化器版本,即使设置了并行提示,Oracle也会忽略并行,而采用串行索引范围扫描执行计划。


    即使都是索引串行扫描,11.2和12c中还是有一点小差异的。在12c中,Oracle引入了批量ROWID提取的新特性,在执行计划中由关键字BATCHED标识。可以看到11.2和12c中执行效率也有很小的差异,而这个性能提升就是这个批量处理新特性带来的。


    Oracle无法采用并行执行的原因是由索引的存储结构决定的,当执行索引访问时,Oracle首先定位到Btree索引的根节点,通过与根节点中存储的键值前缀进行比较,定位到枝叶节点,重复比较的过程,最终定位到叶子节点。在叶子节点上Oracle找到了第一条满足条件的键值,然后Oracle会根据叶节点上的链表扫描下一个叶节点,不断重复这个过程,直到不满足查询限制条件的记录出现。


    也就是说Oracle需要根据顺序访问一条链表,只有找到第一个索引块才知道下一个要访问的索引块在哪里,因此这个过程没有办法拆分到多个进程同时执行,这就是为什么索引范围扫描一直无法并行的原因。



    产品推荐

    云和恩墨zData一体机现已发布超融合版本和精简版,支持各种简化场景部署,零数据丢失备份一体机ZDBM也已发布,欢迎关注。

    640?wx_fmt=jpeg



    实现索引扫描并行执行

    640?wx_fmt=other

    Oracle在12c中使得索引扫描可以并行执行,下面看看Oracle是如何实现的:

    SQL> select /*+ index(t) parallel(2) */ count(name) from t_para_ind t where created >= to_date('201701', 'yyyymm');

     

    Elapsed: 00:00:00.38

    640?wx_fmt=png


    为了输出格式的可读性,把执行计划中和当前关系不大的列去掉了。


    可以看到Oracle确实采用了并行的执行计划,而且执行时间也比串行执行快。


    如果仔细观察IN-OUT列,就会发现Oracle的并行执行实际上从第6步才开始,第7步是串行到并行的过程,而第7步之前的第9步和第8步都是串行执行。


    也就是说Oracle把索引范围扫描的过程分成了两部分,一部分是之前讨论的索引范围扫描部分,而另一部分是索引扫描后根据rowid的读取表中记录的过程。对于前者,即使是在12c中,Oracle仍然采用串行的扫描方式执行,而对于后者,Oracle将其并行化。这也是性能提升的由来。


    SQL> select /*+ index(t) parallel(4) */ count(name) from t_para_ind t where created >= to_date('201701', 'yyyymm');

     

    Elapsed: 00:00:00.56

     640?wx_fmt=png


    但是这种方式的分拆并不是真正意义的并行,因为其中的一部分是无法并行的,所以当我们进一步加大并行度的时候,执行时间反而变长了。

    SQL> select /*+ index(t) parallel(4) */ count(*) from t_para_ind t where created >= to_date('201701', 'yyyymm');

     

    Elapsed: 00:00:00.17

    640?wx_fmt=png


    而如果我们修改SQL语句,把原本的COUNT(NAME)改为COUNT(*),这时由于执行计划中回表部分不再需要,执行计划只剩下不能并行的索引扫描部分,因此执行计划又恢复了串行执行。这又一次证实了12c的并行索引扫描只是部分并行,其提升总体扫描效率的能力是有限的。


    全表扫描的并行执行

    640?wx_fmt=other

    下面看看全表扫描的并行执行:

    SQL> select count(name) from t_para_ind t where created >= to_date('201701', 'yyyymm');

     

    Elapsed: 00:00:00.24

     640?wx_fmt=png


    串行全表扫描时,执行时间为0.24秒。

    SQL> select /*+ parallel(2) */ count(name) from t_para_ind t where created >= to_date('201701', 'yyyymm');

     

    Elapsed: 00:00:00.15

     640?wx_fmt=png


    开启2路并行时,执行时间为0.15秒。

    SQL> select /*+ parallel(4) */ count(name) from t_para_ind t where created >= to_date('201701', 'yyyymm');

     

    Elapsed: 00:00:00.08

    640?wx_fmt=png


    开启4路并行时,执行时间降低到了0.08秒。显然全表扫描才是真正的并行,在合理的数据量和资源消耗范围内,其执行时间是随着并行度增大而等比降低的。

     


    资源下载

    关注公众号:数据和云(OraNews)回复关键字获取

    2018DTCC , 数据库大会PPT

    2018DTC,2018 DTC 大会 PPT

    DBALIFE ,“DBA 的一天”海报

    DBA04 ,DBA 手记4 电子书

    122ARCH ,Oracle 12.2体系结构图

    2018OOW ,Oracle OpenWorld 资料

    PRELECTION ,大讲堂讲师课程资料

    近期文章

    企业数据架构的云化智能重构和变革(含大会PPT)

    警示2018:那些值得在年底彻查和回顾的数据库事件

    Oracle研发总裁Thomas Kurian加盟Google Cloud

    变与不变: Undo构造一致性读的例外情况

    Oracle 18c新特性:动态 Container Map 增强 

    Oracle 18c新特性:Schema-Only 帐号提升安全性

    Oracle 18c新特性:多租户舰队 CDB Fleet (含PPT)

    为什么看了那么多灾难,还是过不好备份这一关?


    640?wx_fmt=jpeg

  • 相关阅读:
    CentOS6.8上Docker的安装
    IDE- VS Code-插件-Golang
    Tool-Docker-First exploration
    C++-Code-Time Transfer-Windows FILETIME(1601) To 1970 UTC
    Tool-git-command-入门笔记[慕课网-五月的夏天]
    C++-当表达式中同时存在有符号和无符号的类型时,有符号类型先转为无符号参与计算
    C语言-C语言程序设计-Practice code
    C语言-C语言程序设计-Function-strcpy
    C语言-C语言程序设计-Function-fopen
    C语言-C语言程序设计-Application-逆波兰计算器
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13312199.html
Copyright © 2020-2023  润新知