zoukankan      html  css  js  c++  java
  • union 代替or的情况

    技巧2:union 代替or的情况
    
    当SQL语句中,or 条件上面有一个为子查询,并且子查询上的表与源表不同,这个时候就可以用union代替or或者你发现执行计划中的 filter 有 or 并且 or 后面跟上子查询
    
    (EXISTS...)的时候就要注意,比如:
    
    2 - filter("T"."LRR_DM"='e90e3fe4237c4af988477329c7f2059e' OR  
                  "T"."KPR_DM"='e90e3fe4237c4af988477329c7f2059e' OR  EXISTS (SELECT 0 FROM "KHGL_KHYWDLXX" "Y"  WHERE "Y"."KH_ID"=:B1 AND 
    
    "Y"."SSKHJL_DM"='e90e3fe4237c4af988477329c7f2059e'))  
    
    当然了,当你看到operation中的filter也应该要注意这些
    
    示例如下(请自己动手实验):
    
    create table test1 as select * from dba_objects;
    create table test2 as select * from dba_objects;
    create index idx1 on test1(object_id);
    create index idx2 on test1(owner);
    create index idx3 on test2(object_id);
    create index idx4 on test2(owner);
    
    BEGIN
      DBMS_STATS.GATHER_TABLE_STATS(ownname          => 'SCOTT',
                                    tabname          => 'TEST1',
                                    estimate_percent => 100,
                                    method_opt       => 'for  columns owner size 200',
                                    no_invalidate    => FALSE,
                                    degree           => 1,
                                    cascade          => TRUE);
    END;
    /
    
    BEGIN
      DBMS_STATS.GATHER_TABLE_STATS(ownname          => 'SCOTT',
                                    tabname          => 'TEST2',
                                    estimate_percent => 100,
                                    method_opt       => 'for  columns owner size 200',
                                    no_invalidate    => FALSE,
                                    degree           => 1,
                                    cascade          => TRUE);
    END;
    /
    
    比如这个SQL:
    
    select * from test1 where owner='SCOTT' or object_id in(select object_id from test2 where owner='SCOTT');
    
    执行计划如下:
    
    select * from test1 where owner='SCOTT' or object_id in(select object_id from test2 where owner='SCOTT');
    
    1859 rows selected.
    
    
    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 4136318878
    
    ------------------------------------------------------------------------------------------
    | Id  | Operation			 | Name  | Rows  | Bytes | Cost (%CPU)| Time	 |
    ------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT		 |	 |  5493 |   520K|   296   (1)| 00:00:04 |
    |*  1 |  FILTER 			 |	 |	 |	 |	      | 	 |
    |   2 |   TABLE ACCESS FULL		 | TEST1 | 74533 |  7060K|   296   (1)| 00:00:04 |
    |   3 |   BITMAP CONVERSION TO ROWIDS	 |	 |     1 |    19 |     2   (0)| 00:00:01 |
    |   4 |    BITMAP AND			 |	 |	 |	 |	      | 	 |
    |   5 |     BITMAP CONVERSION FROM ROWIDS|	 |	 |	 |	      | 	 |
    |*  6 |      INDEX RANGE SCAN		 | IDX3  |  1860 |	 |     1   (0)| 00:00:01 |
    |   7 |     BITMAP CONVERSION FROM ROWIDS|	 |	 |	 |	      | 	 |
    |*  8 |      INDEX RANGE SCAN		 | IDX4  |  1860 |	 |     1   (0)| 00:00:01 |
    ------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       1 - filter("OWNER"='SCOTT' OR  EXISTS (SELECT 0 FROM "TEST2" "TEST2" WHERE
    	      "OBJECT_ID"=:B1 AND "OWNER"='SCOTT'))
       6 - access("OBJECT_ID"=:B1)
       8 - access("OWNER"='SCOTT')
    
    
    Statistics
    ----------------------------------------------------------
    	  1  recursive calls
    	  0  db block gets
         475201  consistent gets
    	  0  physical reads
    	  0  redo size
          70860  bytes sent via SQL*Net to client
           1772  bytes received via SQL*Net from client
    	125  SQL*Net roundtrips to/from client
    	  0  sorts (memory)
    	  0  sorts (disk)
           1859  rows processed
    
    
    
    
    将SQL改写成UNION形式:
    
    SQL> select * from test1 where owner='SCOTT' 
    union
    select * from test1 where object_id in(select object_id from test2 where owner='SCOTT');  2    3  
    
    1859 rows selected.
    
    
    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 1667050602
    
    ------------------------------------------------------------------------------------------------
    | Id  | Operation		       | Name  | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
    ------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT	       |       |  3719 |   386K|       |   502	(81)| 00:00:07 |
    |   1 |  SORT UNIQUE		       |       |  3719 |   386K|   553K|   502	(81)| 00:00:07 |
    |   2 |   UNION-ALL		       |       |       |       |       |	    |	       |
    |   3 |    TABLE ACCESS BY INDEX ROWID | TEST1 |  1859 |   176K|       |    55	 (0)| 00:00:01 |
    |*  4 |     INDEX RANGE SCAN	       | IDX2  |  1859 |       |       |     5	 (0)| 00:00:01 |
    |*  5 |    HASH JOIN		       |       |  1860 |   210K|       |   352	 (1)| 00:00:05 |
    |   6 |     TABLE ACCESS BY INDEX ROWID| TEST2 |  1860 | 35340 |       |    55	 (0)| 00:00:01 |
    |*  7 |      INDEX RANGE SCAN	       | IDX4  |  1860 |       |       |     5	 (0)| 00:00:01 |
    |   8 |     TABLE ACCESS FULL	       | TEST1 | 74533 |  7060K|       |   296	 (1)| 00:00:04 |
    ------------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       4 - access("OWNER"='SCOTT')
       5 - access("OBJECT_ID"="OBJECT_ID")
       7 - access("OWNER"='SCOTT')
    
    
    Statistics
    ----------------------------------------------------------
    	  1  recursive calls
    	  0  db block gets
           1131  consistent gets
    	  0  physical reads
    	  0  redo size
          79068  bytes sent via SQL*Net to client
           1772  bytes received via SQL*Net from client
    	125  SQL*Net roundtrips to/from client
    	  1  sorts (memory)
    	  0  sorts (disk)
           1859  rows processed
    
    逻辑读从475201降到1131,性能提升非常明显。
    
    
    

  • 相关阅读:
    笔记
    【转】并行类加载——让tomcat玩转双十一 @双十一实战
    Twitter Snowflake 生成唯一id java版本
    nginx添加 nginx_heath模块
    谁在关心toString的性能?
    HashMap的工作原理
    修改nginx版本名称伪装任意web server
    nginx concat模块配置 页面返回400 bad request
    linux 安装rz sz命令
    nginx 添加nginx-http-concat模块
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13352409.html
Copyright © 2011-2022 走看看