zoukankan      html  css  js  c++  java
  • Oracle Filter执行计划

     一、表关联时执行计划filter代表什么?

     

    http://www.oracleplus.net/arch/1026.html
    
    
    实验数据准备
    SQL> create table scott.htz1 as select * from dba_objects;
    SQL> create table scott.htz2 as select * from dba_objects;
    SQL> create table scott.htz3 as select * from dba_objects;
    SQL> create index scott.ind_htz3_object_owner on scott.htz3(object_id,owner);
    set linesize 500
    set termout off
    alter session set statistics_level=all;
    SQL> host cat plan.sql
    set linesize 200 pagesize 999
    
    
    测试一、驱动表无重复值
    SQL>
     select *
    from scott.htz1 a, scott.htz2 b
    where a.object_id = b.object_id
    and a.object_id in (select object_id
    from scott.htz3 c
    where c.owner = 'SCOTT'
    and a.owner = 'SYS')
    ;
    select * from table(dbms_xplan.display_cursor(null,null,'advanced -PROJECTION -bytes iostats,last'));
    Plan hash value: 1177288075
    ----------------------------------------------------------------------------------------------------------------------------------
    | Id  | Operation              | Name                  | Starts | E-Rows | Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers |
    ----------------------------------------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT       |                       |      1 |        |   772 (100)|          |      0 |00:00:00.06 |    1519 |
    |*  1 |  HASH JOIN             |                       |      1 |     14 |   772   (1)| 00:00:10 |      0 |00:00:00.06 |    1519 |
    |*  2 |   HASH JOIN RIGHT SEMI |                       |      1 |     14 |   424   (1)| 00:00:06 |      0 |00:00:00.06 |    1519 |
    |*  3 |    INDEX FAST FULL SCAN| IND_HTZ3_OBJECT_OWNER |      1 |     14 |    77   (0)| 00:00:01 |     64 |00:00:00.02 |     270 |
    |*  4 |    TABLE ACCESS FULL   | HTZ1                  |      1 |  37820 |   347   (1)| 00:00:05 |  37820 |00:00:00.02 |    1249 |
    |   5 |   TABLE ACCESS FULL    | HTZ2                  |      0 |  97015 |   347   (1)| 00:00:05 |      0 |00:00:00.01 |       0 |
    ----------------------------------------------------------------------------------------------------------------------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
       1 - access("A"."OBJECT_ID"="B"."OBJECT_ID")
       2 - access("A"."OBJECT_ID"="OBJECT_ID")
       3 - filter("C"."OWNER"='SCOTT')
       4 - filter("A"."OWNER"='SYS')
    
    --想整一个 filter执行计划! 不出来,说明Oracle 版本升级后优化器确实存在内部提升!
     select  * 
    from scott.htz1 a, scott.htz2 b
    where a.object_id = b.object_id
    and a.object_id in
     (select /*+ NO_USE_HASH(c) */ object_id
    from scott.htz3 c
    where c.owner = 'SCOTT'
    and a.owner = 'SYS')
    ;
    select * from table(dbms_xplan.display_cursor(null,null,'advanced -PROJECTION -bytes iostats,last'));
    
    参考
    https://www.cndba.cn/cndba/dave/article/4352
    
     select  /*+ optimizer_features_enable('10.2.0.5') */ * 
    from scott.htz1 a, scott.htz2 b
    where a.object_id = b.object_id
    and a.object_id in
     (select object_id
    from scott.htz3 c
    where c.owner = 'SCOTT'
    and a.owner = 'SYS')
    ;
    select * from table(dbms_xplan.display_cursor(null,null,'advanced -PROJECTION -bytes iostats,last'));
    Plan hash value: 286543034
    ----------------------------------------------------------------------------------------------------------------------------------------
    | Id  | Operation           | Name                  | Starts | E-Rows | Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers | Reads  |
    ----------------------------------------------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT    |                       |      1 |        | 80894 (100)|          |      0 |00:00:00.78 |   41608 |    926 |
    |*  1 |  FILTER             |                       |      1 |        |            |          |      0 |00:00:00.78 |   41608 |    926 |
    |*  2 |   HASH JOIN         |                       |      1 |  80459 |  2533   (1)| 00:00:31 |  87117 |00:00:00.52 |    2498 |    926 |
    |   3 |    TABLE ACCESS FULL| HTZ1                  |      1 |  80459 |   347   (1)| 00:00:05 |  87119 |00:00:00.05 |    1249 |      0 |
    |   4 |    TABLE ACCESS FULL| HTZ2                  |      1 |  97015 |   347   (1)| 00:00:05 |  87120 |00:00:00.08 |    1249 |    926 |
    |*  5 |   FILTER            |                       |  87117 |        |            |          |      0 |00:00:00.14 |   39110 |      0 |
    |*  6 |    INDEX RANGE SCAN | IND_HTZ3_OBJECT_OWNER |  37819 |      1 |     1   (0)| 00:00:01 |      0 |00:00:00.10 |   39110 |      0 |
    ----------------------------------------------------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
       1 - filter( IS NOT NULL)
       2 - access("A"."OBJECT_ID"="B"."OBJECT_ID")
       5 - filter(:B1='SYS')
       6 - access("OBJECT_ID"=:B1 AND "C"."OWNER"='SCOTT')
    
    select count(*) from scott.htz1 a, scott.htz2 b
    where a.object_id = b.object_id;
      COUNT(*)
    ----------
         87117
    select count(*) from (
    select distinct a.object_id from scott.htz1 a, scott.htz2 b
    where a.object_id = b.object_id);
      COUNT(*)
    ----------
         87117
         
    select count(*) from (
    select distinct a.object_id from scott.htz1 a, scott.htz2 b
    where a.object_id = b.object_id and a.owner='SYS');     
      COUNT(*)
    ----------
         37819
         
    !!!Filter 驱动表的需要循环执行的次数,是驱动结果集的数量!
         
    --index scott.ind_htz3_object_owner    [object_id,owner]
    select count(*) from (
    select object_id,owner from scott.htz3 group by object_id,owner);
      COUNT(*)
    ----------
         87121
    
    测试二、驱动表存在重复值
    SQL> insert into scott.htz1 select * from scott.htz1;
    commit;
    
     select  /*+ optimizer_features_enable('10.2.0.5') */ * 
    from scott.htz1 a, scott.htz2 b
    where a.object_id = b.object_id
    and a.object_id in
     (select object_id
    from scott.htz3 c
    where c.owner = 'SCOTT'
    and a.owner = 'SYS')
    ;
    select * from table(dbms_xplan.display_cursor(null,null,'advanced -PROJECTION -bytes iostats,last'));
    -------------------------------------------------------------------------------------------------------------------------------
    | Id  | Operation           | Name                  | Starts | E-Rows | Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers |
    -------------------------------------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT    |                       |      1 |        |   291K(100)|          |      0 |00:00:01.13 |   86565 |
    |*  1 |  FILTER             |                       |      1 |        |            |          |      0 |00:00:01.13 |   86565 |
    |*  2 |   HASH JOIN         |                       |      1 |    288K|  5409   (1)| 00:01:05 |    174K|00:00:00.69 |    3767 |
    |   3 |    TABLE ACCESS FULL| HTZ2                  |      1 |  97015 |   347   (1)| 00:00:05 |  87120 |00:00:00.03 |    1249 |
    |   4 |    TABLE ACCESS FULL| HTZ1                  |      1 |    324K|   694   (1)| 00:00:09 |    174K|00:00:00.06 |    2518 |
    |*  5 |   FILTER            |                       |    173K|        |            |          |      0 |00:00:00.26 |   82798 |
    |*  6 |    INDEX RANGE SCAN | IND_HTZ3_OBJECT_OWNER |  74784 |      1 |     1   (0)| 00:00:01 |      0 |00:00:00.17 |   82798 |
    -------------------------------------------------------------------------------------------------------------------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
       1 - filter( IS NOT NULL)
       2 - access("A"."OBJECT_ID"="B"."OBJECT_ID")
       5 - filter(:B1='SYS')
       6 - access("OBJECT_ID"=:B1 AND "C"."OWNER"='SCOTT')
    
    select count(*) from scott.htz1 a, scott.htz2 b
    where a.object_id = b.object_id;
      COUNT(*)
    ----------
        174234
        
    select count(*) from (
    select distinct a.object_id from scott.htz1 a, scott.htz2 b
    where a.object_id = b.object_id);
      COUNT(*)
    ----------
         87117
         
    select count(*) from (
    select distinct a.object_id from scott.htz1 a, scott.htz2 b
    where a.object_id = b.object_id and a.owner='SYS');          
      COUNT(*)
    ----------
         37819
         
    select count(*) from (
    select a.object_id from scott.htz1 a, scott.htz2 b
    where a.object_id = b.object_id and a.owner='SYS');
      COUNT(*)
    ----------
         75638
    
    select count(*) from scott.htz3;
    87121
    select count(*) from scott.htz3 where owner='SCOTT';
    64
    
    select count(*) from (
    select tmp_b.object_id from (
    select a.object_id from scott.htz1 a, scott.htz2 b
    where a.object_id = b.object_id) tmp_a,scott.htz1 tmp_b 
     where tmp_a.object_id=tmp_b.object_id and tmp_b.owner='SYS');
      COUNT(*)
    ----------
        151276
    select count(*) from (
    select  distinct tmp_b.object_id from (
    select a.object_id from scott.htz1 a, scott.htz2 b
    where a.object_id = b.object_id) tmp_a,scott.htz1 tmp_b 
     where tmp_a.object_id=tmp_b.object_id and tmp_b.owner='SYS');
      COUNT(*)
    ----------
         37819
    select count(*) from (
    select  tmp_b.object_id from (
    select a.object_id from scott.htz1 a, scott.htz2 b
    where a.object_id = b.object_id and a.owner='SYS') tmp_a,scott.htz1 tmp_b 
     where tmp_a.object_id=tmp_b.object_id );
         
     select  * 
    from scott.htz1 a, scott.htz2 b
    where a.object_id = b.object_id
    and a.object_id in
     (select /*+ no_unnest */ object_id
    from scott.htz3 c
    where c.owner = 'SCOTT'
    and a.owner = 'SYS')
    ;
    select * from table(dbms_xplan.display_cursor(null,null,'advanced -PROJECTION -bytes iostats,last'));
    -------------------------------------------------------------------------------------------------------------------------------
    | Id  | Operation           | Name                  | Starts | E-Rows | Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers |
    -------------------------------------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT    |                       |      1 |        |  2663 (100)|          |      0 |00:00:00.53 |   42877 |
    |*  1 |  FILTER             |                       |      1 |        |            |          |      0 |00:00:00.53 |   42877 |
    |*  2 |   HASH JOIN         |                       |      1 |   3246 |  1040   (1)| 00:00:13 |  75638 |00:00:00.33 |    3767 |
    |*  3 |    TABLE ACCESS FULL| HTZ1                  |      1 |   3246 |   692   (1)| 00:00:09 |  75640 |00:00:00.04 |    2518 |
    |   4 |    TABLE ACCESS FULL| HTZ2                  |      1 |  97015 |   347   (1)| 00:00:05 |  87120 |00:00:00.04 |    1249 |
    |*  5 |   INDEX RANGE SCAN  | IND_HTZ3_OBJECT_OWNER |  37819 |      1 |     1   (0)| 00:00:01 |      0 |00:00:00.12 |   39110 |
    -------------------------------------------------------------------------------------------------------------------------------

    小结:

         测试了一下filter 在表关联的情况下,类似nest loop, 驱动的结果集有多少,被驱动结果集需要重复执行多少次。   

         但是filter优化了nest loop, 就是假设驱动结果集记录500,distinct 之后是60,那么被驱动的结果集只需要执行60次。     具体可以测试以及学习基于Oracle SQL优化。

         本次测试11.2.0.4 DB版本,使用Hint sql 10.2.0.5优化器参数后, 驱动表无重复值,start次数符合预期,但是驱动表存在重复值后,start与预期不符合。  sql重新使用11.2.0.4 优化器参数后,start 次数符合预期!!!

         也就是说当出现filter时,可以类似用nest loop的方式考虑!  但是驱动次数=去重后的驱动结果集数量!

    二、相关优化器参数

     

    https://blog.csdn.net/cuiqu77884/article/details/100338813
    11g 默认参数为true
    create table t1 as select * from dba_objects; create table t2 as select * from dba_tables; select count(*) from t1 where object_name not in (select table_name from t2); COUNT(*) ---------- 83859 select * from table(dbms_xplan.display_cursor(null,null,'advanced -PROJECTION -bytes iostats,last')); ----------------------------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Starts | E-Rows | Cost (%CPU)| E-Time | A-Rows | A-Time | Buffers | Reads | ----------------------------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | 379 (100)| | 1 |00:00:00.21 | 1355 | 879 | | 1 | SORT AGGREGATE | | 1 | 1 | | | 1 |00:00:00.21 | 1355 | 879 | |* 2 | HASH JOIN RIGHT ANTI SNA| | 1 | 90231 | 379 (1)| 00:00:05 | 83859 |00:00:00.20 | 1355 | 879 | | 3 | TABLE ACCESS FULL | T2 | 1 | 2771 | 32 (0)| 00:00:01 | 2927 |00:00:00.01 | 106 | 0 | | 4 | TABLE ACCESS FULL | T1 | 1 | 90231 | 347 (1)| 00:00:05 | 87121 |00:00:00.13 | 1249 | 879 | ----------------------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("OBJECT_NAME"="TABLE_NAME") SQL> alter session set "_optimizer_null_aware_antijoin"=false; select count(*) from t1 where object_name not in (select table_name from t2); select * from table(dbms_xplan.display_cursor(null,null,'advanced -PROJECTION -bytes iostats,last')); --等待16s还是没有执行完毕,手工取消执行 -------------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Starts | E-Rows | Cost (%CPU)| E-Time | A-Rows | A-Time | Buffers | -------------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | 120K(100)| | 0 |00:00:00.01 | 0 | | 1 | SORT AGGREGATE | | 1 | 1 | | | 0 |00:00:00.01 | 0 | |* 2 | FILTER | | 1 | | | | 63977 |00:00:16.00 | 3963K| | 3 | TABLE ACCESS FULL| T1 | 1 | 90231 | 347 (1)| 00:00:05 | 65341 |00:00:00.03 | 939 | |* 4 | TABLE ACCESS FULL| T2 | 38236 | 2633 | 2 (0)| 00:00:01 | 1249 |00:00:15.75 | 3962K| -------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - filter( IS NULL) 4 - filter(LNNVL("TABLE_NAME"<>:B1))
    _optimizer_null_aware_antijoin参数能优化查询效率,但是查看mos,开启该隐含参数会有很多的bug。可能存在不稳定,因此通常会建议把该参数关闭。 
    这个参数默认true开启状态,会自动将filter执行计划调整为hash,如果关闭之后就出现filter了!
    ! 如果执行计划发行存在filter之后,并且参数false,可以尝试SQL语句Hint 参数=true观察,hash是否有所提升!

      

  • 相关阅读:
    利用相关的Aware接口
    java 值传递和引用传递。
    权限控制框架Spring Security 和Shiro 的总结
    优秀代码养成
    Servlet 基础知识
    leetcode 501. Find Mode in Binary Search Tree
    leetcode 530. Minimum Absolute Difference in BST
    leetcode 543. Diameter of Binary Tree
    leetcode 551. Student Attendance Record I
    leetcode 563. Binary Tree Tilt
  • 原文地址:https://www.cnblogs.com/lvcha001/p/14360967.html
Copyright © 2011-2022 走看看