• 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是否有所提升!

      

  • 相关阅读:
    好用的抓取dump的工具-ProcDump
    好用的抓取dump的工具-ProcDump
    使用Windbg调试系统弹出的内存不可读错误
    使用Windbg调试系统弹出的内存不可读错误
    驱动层hook系统函数的时,如何屏蔽掉只读属性?
    Rootkit之SSDT hook(通过CR0)
    Rootkit之SSDT hook(通过CR0)
    #define SYSTEMSERVICE(_func) KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)_func+1) 这
    华南理工大学“三七互娱杯”程序设计竞赛(重现赛)B HRY and fibonacci
    华南理工大学“三七互娱杯”程序设计竞赛(重现赛)A HRY and codefire
  • 原文地址:https://www.cnblogs.com/lvcha001/p/14360967.html
Copyright © 2020-2023  润新知