zoukankan      html  css  js  c++  java
  • 走FILTER效率高的2种情况

    FILTER的适用范围:
    1. 主表返回的记录数较少
    
    2.子查询返回记录数较小
    下面做实验证明:
    select department_name
      from hr.dept_1 dept
     where department_id IN (select department_id from hr.employees_1 emp);
    
    SQL>  select count(*) from dept_1;
    
      COUNT(*)
    ----------
    	 2
    
    SQL>  select count(*) from employees_1;
    
      COUNT(*)
    ----------
       3506176
    
    SQL> select department_name
      from hr.dept_1 dept
     where department_id IN (select department_id from hr.employees_1 emp);  2    3  
    
    
    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 3257593059
    
    ---------------------------------------------------------------------------------------
    | Id  | Operation	   | Name	      | Rows  | Bytes | Cost (%CPU)| Time     |
    ---------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT   |		      |     2 |    40 |     7	(0)| 00:00:01 |
    |   1 |  NESTED LOOPS SEMI |		      |     2 |    40 |     7	(0)| 00:00:01 |
    |   2 |   TABLE ACCESS FULL| DEPT_1	      |     2 |    32 |     3	(0)| 00:00:01 |
    |*  3 |   INDEX RANGE SCAN | EMPLOYEES_1_IDX1 |  3508K|    13M|     2	(0)| 00:00:01 |
    ---------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       3 - access("DEPARTMENT_ID"="DEPARTMENT_ID")
    
    
    Statistics
    ----------------------------------------------------------
    	  0  recursive calls
    	  0  db block gets
    	 10  consistent gets
    	  0  physical reads
    	  0  redo size
    	486  bytes sent via SQL*Net to client
    	419  bytes received via SQL*Net from client
    	  2  SQL*Net roundtrips to/from client
    	  0  sorts (memory)
    	  0  sorts (disk)
    	  2  rows processed
    
    
    那么走FILTER呢?
    SQL> select department_name
      from hr.dept_1 dept
     where department_id IN (select /*+ NO_UNNEST */ department_id from hr.employees_1 emp);  2    3  
    
    
    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 1766326341
    
    ---------------------------------------------------------------------------------------
    | Id  | Operation	   | Name	      | Rows  | Bytes | Cost (%CPU)| Time     |
    ---------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT   |		      |     1 |    16 |     6	(0)| 00:00:01 |
    |*  1 |  FILTER 	   |		      |       |       | 	   |	      |
    |   2 |   TABLE ACCESS FULL| DEPT_1	      |     2 |    32 |     3	(0)| 00:00:01 |
    |*  3 |   INDEX RANGE SCAN | EMPLOYEES_1_IDX1 |     2 |     8 |     3	(0)| 00:00:01 |
    ---------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       1 - filter( EXISTS (SELECT /*+ NO_UNNEST */ 0 FROM "HR"."EMPLOYEES_1" "EMP"
    	      WHERE "DEPARTMENT_ID"=:B1))
       3 - access("DEPARTMENT_ID"=:B1)
    
    
    Statistics
    ----------------------------------------------------------
    	  0  recursive calls
    	  0  db block gets
    	 10  consistent gets
    	  0  physical reads
    	  0  redo size
    	486  bytes sent via SQL*Net to client
    	419  bytes received via SQL*Net from client
    	  2  SQL*Net roundtrips to/from client
    	  0  sorts (memory)
    	  0  sorts (disk)
    	  2  rows processed
    
    
    
    此时效率一样,说明当from ...主表 返回数据 只返回几条 走FILTER没问题(主表小是之返回行数少)
    
    
    那么还有什么情况,可以走FILTER呢?
    
    SQL>  select * from test a where object_id in (select   department_id
      from hr.dept_1 dept
     where department_id IN (select   department_id from hr.employees_1 emp));  2    3  
    
    64 rows selected.
    
    
    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 717021958
    
    --------------------------------------------------------------------------------------------
    | Id  | Operation		| Name		   | Rows  | Bytes | Cost (%CPU)| Time	   |
    --------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT	|		   |	 1 |   207 |  9747   (7)| 00:01:57 |
    |   1 |  VIEW			| VM_NWVW_2	   |	 1 |   207 |  9747   (7)| 00:01:57 |
    |   2 |   HASH UNIQUE		|		   |	 1 |   226 |  9747   (7)| 00:01:57 |
    |*  3 |    HASH JOIN		|		   |	14M|  3134M|  9264   (2)| 00:01:52 |
    |*  4 |     HASH JOIN		|		   |	46 | 10212 |  7400   (1)| 00:01:29 |
    |   5 |      TABLE ACCESS FULL	| DEPT_1	   |	 2 |	 6 |	 3   (0)| 00:00:01 |
    |   6 |      TABLE ACCESS FULL	| TEST		   |  2511K|   524M|  7389   (1)| 00:01:29 |
    |   7 |     INDEX FAST FULL SCAN| EMPLOYEES_1_IDX1 |  3508K|	13M|  1819   (1)| 00:00:22 |
    --------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       3 - access("DEPARTMENT_ID"="DEPARTMENT_ID")
       4 - access("OBJECT_ID"="DEPARTMENT_ID")
    
    Note
    -----
       - dynamic sampling used for this statement (level=2)
    
    
    Statistics
    ----------------------------------------------------------
    	  0  recursive calls
    	  0  db block gets
          57221  consistent gets
          41372  physical reads
    	  0  redo size
           2850  bytes sent via SQL*Net to client
    	463  bytes received via SQL*Net from client
    	  6  SQL*Net roundtrips to/from client
    	  0  sorts (memory)
    	  0  sorts (disk)
    	 64  rows processed
    
    
    这里子查询被展开了,导致test和dept_1先关联了,但是子查询
    SQL> (select   department_id
      from hr.dept_1 dept
     where department_id IN (select   department_id from hr.employees_1 emp))  2    3  ;
    
    DEPARTMENT_ID
    -------------
    	   10
    	   20
    只返回了2条记录,可以让它走FILTER。
    
    SQL> select * from test a where object_id in (select  department_id
      from hr.dept_1 dept
     where department_id IN (select /*+ NO_UNNEST */  department_id from hr.employees_1 emp));  2    3  
    
    64 rows selected.
    
    
    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 1506439343
    
    -----------------------------------------------------------------------------------------
    | Id  | Operation	     | Name		| Rows	| Bytes | Cost (%CPU)| Time	|
    -----------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT     |			|    23 |  5060 |  7403   (1)| 00:01:29 |
    |*  1 |  HASH JOIN RIGHT SEMI|			|    23 |  5060 |  7403   (1)| 00:01:29 |
    |   2 |   VIEW		     | VW_NSO_1 	|     1 |    13 |     6   (0)| 00:00:01 |
    |*  3 |    FILTER	     |			|	|	|	     |		|
    |   4 |     TABLE ACCESS FULL| DEPT_1		|     2 |     6 |     3   (0)| 00:00:01 |
    |*  5 |     INDEX RANGE SCAN | EMPLOYEES_1_IDX1 |     2 |     8 |     3   (0)| 00:00:01 |
    |   6 |   TABLE ACCESS FULL  | TEST		|  2511K|   495M|  7389   (1)| 00:01:29 |
    -----------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       1 - access("OBJECT_ID"="DEPARTMENT_ID")
       3 - filter( EXISTS (SELECT /*+ NO_UNNEST */ 0 FROM "HR"."EMPLOYEES_1" "EMP"
    	      WHERE "DEPARTMENT_ID"=:B1))
       5 - access("DEPARTMENT_ID"=:B1)
    
    Note
    -----
       - dynamic sampling used for this statement (level=2)
    
    
    Statistics
    ----------------------------------------------------------
    	  0  recursive calls
    	  0  db block gets
          48871  consistent gets
          33065  physical reads
    	  0  redo size
           4119  bytes sent via SQL*Net to client
    	463  bytes received via SQL*Net from client
    	  6  SQL*Net roundtrips to/from client
    	  0  sorts (memory)
    	  0  sorts (disk)
    	 64  rows processed
    
    走FILTER后逻辑读下降到了 48871 。
    
    总结如果子查询返回数据很少,那么不妨让它走filter,这种情况如果子查询被展开,那么会导致执行计划混乱,导致大表先和子查询里的大表关联。
    
    
    
    


    
    
    
    
    
    
    
    
    
    
    
                                        
    
  • 相关阅读:
    研究table-cell和overflow
    自己封装jquery的一些方法 链式调用模式
    简单的抖动运动 主要利用offset left 和 setTimeout
    闭包的讲解与简单实用(重新理解)
    操作iframe 的方法与兼容性
    360度全景图片
    数组排序
    怎么让链式调用setTimeout停止
    setInterval 和 setTimeout
    重力碰撞运动的疑惑
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13352322.html
Copyright © 2011-2022 走看看