Filter的一个测试

 
Filter的一个测试:
创建测试表 t1 和t2. 
create table t1 as select * from dba_objects where rownum<=5000;
create table t2 as select * from dba_objects where rownum<=5000;

执行该测试SQL,这里使用了提示来收集真实的执行计划
select /*+ gather_plan_statistics */
 count(*)
  from t1
 where exists (select 1
          from t2
         where t2.owner = t1.owner
         group by t2.object_type
        having count(*) >= 10)
   and t1.object_type = 'TABLE';


set autot off;
 
select /*+ gather_plan_statistics */
 count(*)
  from t1
 where exists (select 1
          from t2
         where t2.owner = t1.owner
         group by t2.object_type
        having count(*) >= 10)
   and t1.object_type = 'TABLE';

  COUNT(*)
----------
       519

SQL> select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));

PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------
---------------
SQL_ID  49t0m3dv35346, child number 0
-------------------------------------
select /*+ gather_plan_statistics */  count(*)   from t1  where exists
(select 1           from t2          where t2.owner = t1.owner
group by t2.object_type         having count(*) >= 10)    and
t1.object_type = 'TABLE'

Plan hash value: 2091197476

-----------------------------------------------------------------------------------------------
--------------------
| Id  | Operation             | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem
|  1Mem | Used-Mem |
-----------------------------------------------------------------------------------------------
--------------------
|   0 | SELECT STATEMENT      |      |      1 |        |      1 |00:00:00.01 |     268 |
|       |         |
|   1 |  SORT AGGREGATE       |      |      1 |      1 |      1 |00:00:00.01 |     268 |
|       |         |
|*  2 |   FILTER              |      |      1 |        |    519 |00:00:00.01 |     268 |
|       |         |
|*  3 |    TABLE ACCESS FULL  | T1   |      1 |    587 |    522 |00:00:00.01 |      67 |
|       |         |
|*  4 |    FILTER             |      |      3 |        |      2 |00:00:00.01 |     201 |
|       |         |
|   5 |     HASH GROUP BY     |      |      3 |     50 |      8 |00:00:00.01 |     201 |  1301K|  1301K| 1074K (0)|

|*  6 |      TABLE ACCESS FULL| T2   |      3 |     50 |   3449 |00:00:00.01 |     201 |
|       |         |
-----------------------------------------------------------------------------------------------
--------------------

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

   2 - filter( IS NOT NULL)
   3 - filter("T1"."OBJECT_TYPE"='TABLE')
   4 - filter(COUNT(*)>=10)
   6 - filter("T2"."OWNER"=:B1)

Note
-----
   - dynamic sampling used for this statement (level=2)


已选择33行。
①Starts的意思是执行了几次,首先2这个地方执行了1次,是对t1进行全表扫描,返回了522行记录,
测试如下:
SQL> select count(*) from t1 where t1.object_type = 'TABLE';

  COUNT(*)
----------
       522
②看 一下4这个结点,执行了3次, 测试:

SQL> select distinct owner from t1 where t1.object_type = 'TABLE';

OWNER
------------------------------
OUTLN
SYSTEM
SYS
总结:
1.Filter就是外部查询返回多少个唯一值,内部查询就访问多少次。
2.产生Filter的方式:
①exists里有group by xx having xx
②exists里有rownum 或者是start with时会产生filter.
3.filter的执行计划一般是不好的,因为外部返回的数据很大的话,就会导致内部查询扫描很多次。
改写exists:
这样改写的原因是owner是传值,其实也就是相当于对owner分组 
   
select /*+ gather_plan_statistics */
 count(*)
  from t1
 where  owner in (select owner
          from t2
         group by t2.object_type,owner
        having count(*) >= 10)
   and t1.object_type = 'TABLE';
   select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));
   
   
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------
SQL_ID  c07dgxq09xqga, child number 0
-------------------------------------
select /*+ gather_plan_statistics */  count(*)   from t1  where  owner
in (select owner           from t2          group by
t2.object_type,owner         having count(*) >= 10)    and
t1.object_type = 'TABLE'

Plan hash value: 3015395397

-------------------------------------------------------------------------------------------------------------------------
| Id  | Operation               | Name     | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
-------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT        |          |      1 |        |      1 |00:00:00.01 |     134 |       |       |          |
|   1 |  SORT AGGREGATE         |          |      1 |      1 |      1 |00:00:00.01 |     134 |       |       |          |
|*  2 |   HASH JOIN SEMI        |          |      1 |    587 |    519 |00:00:00.01 |     134 |  2293K|  2293K|  561K (0)|
|   3 |    JOIN FILTER CREATE   | :BF0000  |      1 |    587 |    522 |00:00:00.01 |      67 |       |       |          |
|*  4 |     TABLE ACCESS FULL   | T1       |      1 |    587 |    522 |00:00:00.01 |      67 |       |       |          |
|   5 |    VIEW                 | VW_NSO_1 |      1 |   5002 |     10 |00:00:00.01 |      67 |       |       |          |
|*  6 |     FILTER              |          |      1 |        |     10 |00:00:00.01 |      67 |       |       |          |
|   7 |      HASH GROUP BY      |          |      1 |   5002 |     21 |00:00:00.01 |      67 |  1214K|  1214K| 1249K (0)|
|   8 |       JOIN FILTER USE   | :BF0000  |      1 |   5002 |   3449 |00:00:00.01 |      67 |       |       |          |
|*  9 |        TABLE ACCESS FULL| T2       |      1 |   5002 |   3449 |00:00:00.01 |      67 |       |       |          |
-------------------------------------------------------------------------------------------------------------------------

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

   2 - access("OWNER"="OWNER")
   4 - filter("T1"."OBJECT_TYPE"='TABLE')
   6 - filter(COUNT(*)>=10)
   9 - filter(SYS_OP_BLOOM_FILTER(:BF0000,"OWNER"))

Note
-----
   - dynamic sampling used for this statement (level=2)


已选择36行。

 

你可能感兴趣的:(Development)