如何让in/exists 子查询(半连接)作为驱动表?

怎么才能让子查询作为驱动表? SQL如下:

  1. select  rowid rid  
  2.    from its_car_pass7 v  
  3.   where 1 = 1  
  4.     and pass_datetime >=  
  5.         to_date('2013-07-06 :17:46:04', 'yyyy-mm-dd hh24:mi:ss')  
  6.     and pass_datetime <=  
  7.         to_date('2013-07-06 :18:46:06', 'yyyy-mm-dd hh24:mi:ss')  
  8.     and v.pass_device_unid in  
  9.         (select unid  
  10.            from its_base_device  
  11.           where dev_bay_unid in ('01685EFE4658C19D59C4DDAAEDD37393')  
  12.             and dev_type = '1'  
  13.             and dev_chk_flag = '1'  
  14.             and dev_delete_flag = 'N')  
  15.   order by v.pass_datetime asc   
  16.  /  

执行计划如下:

  1. Execution Plan  
  2. ----------------------------------------------------------  
  3. Plan hash value: 3634433140  
  4.   
  5. --------------------------------------------------------------------------------------------------------------------  
  6. | Id  | Operation                     | Name               | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |  
  7. --------------------------------------------------------------------------------------------------------------------  
  8. |   0 | SELECT STATEMENT              |                    |     1 |   111 |     2  (50)| 00:00:01 |       |       |  
  9. |   1 |  SORT ORDER BY                |                    |     1 |   111 |     2  (50)| 00:00:01 |       |       |  
  10. |   2 |   NESTED LOOPS                |                    |       |       |            |          |       |       |  
  11. |   3 |    NESTED LOOPS               |                    |     1 |   111 |     1   (0)| 00:00:01 |       |       |  
  12. |   4 |     PARTITION RANGE SINGLE    |                    |     1 |    39 |     1   (0)| 00:00:01 |  1284 |  1284 |  
  13. |*  5 |      INDEX SKIP SCAN          | IDX_VT7_DEVICEID   |     1 |    39 |     1   (0)| 00:00:01 |  1284 |  1284 |  
  14. |*  6 |     INDEX UNIQUE SCAN         | PK_ITS_BASE_DEVICE |     1 |       |     0   (0)| 00:00:01 |       |       |  
  15. |*  7 |    TABLE ACCESS BY INDEX ROWID| ITS_BASE_DEVICE    |     1 |    72 |     0   (0)| 00:00:01 |       |       |  
  16. --------------------------------------------------------------------------------------------------------------------  
  17.   
  18. Predicate Information (identified by operation id):  
  19. ---------------------------------------------------  
  20.   
  21.    5 - access("PASS_DATETIME">=TO_DATE(' 2013-07-06 17:46:04', 'syyyy-mm-dd hh24:mi:ss') AND  
  22.               "PASS_DATETIME"<=TO_DATE(' 2013-07-06 18:46:06', 'syyyy-mm-dd hh24:mi:ss'))  
  23.        filter("PASS_DATETIME">=TO_DATE(' 2013-07-06 17:46:04', 'syyyy-mm-dd hh24:mi:ss') AND  
  24.               "PASS_DATETIME"<=TO_DATE(' 2013-07-06 18:46:06', 'syyyy-mm-dd hh24:mi:ss'))  
  25.    6 - access("V"."PASS_DEVICE_UNID"="UNID")  
  26.    7 - filter("DEV_BAY_UNID"='01685EFE4658C19D59C4DDAAEDD37393' AND "DEV_TYPE"='1' AND  
  27.               "DEV_DELETE_FLAG"='N' AND "DEV_CHK_FLAG"='1')  
  28.   
  29.   
  30. Statistics  
  31. ----------------------------------------------------------  
  32.           1  recursive calls  
  33.           0  db block gets  
  34.      110973  consistent gets  
  35.           0  physical reads  
  36.           0  redo size  
  37.       47861  bytes sent via SQL*Net to client  
  38.        1656  bytes received via SQL*Net from client  
  39.         105  SQL*Net roundtrips to/from client  
  40.           1  sorts (memory)  
  41.           0  sorts (disk)  
  42.        1560  rows processed  

这里我们就不管统计信息是否准确了,也不管SQL优化的问题,就单单讨论哥们问的问题吧。

那哥们说,怎么才能让子查询作为驱动表呢?他自己试了很多方法就是搞不定。 那我们来亲自搞搞吧

  1. explain plan for   select  rowid rid  
  2.    from its_car_pass7 v  
  3.   where 1 = 1  
  4.     and pass_datetime >=  
  5.         to_date('2013-07-06 :17:46:04', 'yyyy-mm-dd hh24:mi:ss')  
  6.     and pass_datetime <=  
  7.         to_date('2013-07-06 :18:46:06', 'yyyy-mm-dd hh24:mi:ss')  
  8.     and v.pass_device_unid in  
  9.         (select unid  
  10.            from its_base_device  
  11.           where dev_bay_unid in ('01685EFE4658C19D59C4DDAAEDD37393')  
  12.             and dev_type = '1'  
  13.             and dev_chk_flag = '1'  
  14.             and dev_delete_flag = 'N')  
  15.   order by v.pass_datetime asc   
  16.  /  

执行计划如下

  1. SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY(NULL, NULL, 'ADVANCED -PROJECTION'));  
  2.   
  3. -----------------------------------------------------------  
  4. Plan hash value: 2191740724  
  5. ---------------------------------------------------------------------------------------------------------------------------  
  6. | Id  | Operation                            | Name               | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |  
  7. ---------------------------------------------------------------------------------------------------------------------------  
  8. |   0 | SELECT STATEMENT                     |                    |     1 |   111 |  2092K  (1)| 06:58:26 |       |       |  
  9. |   1 |  NESTED LOOPS                        |                    |       |       |            |          |       |       |  
  10. |   2 |   NESTED LOOPS                       |                    |     1 |   111 |  2092K  (1)| 06:58:26 |       |       |  
  11. |   3 |    PARTITION RANGE SINGLE            |                    |     1 |    39 |  2092K  (1)| 06:58:26 |  1284 |  1284 |  
  12. |   4 |     TABLE ACCESS BY LOCAL INDEX ROWID| ITS_CAR_PASS7      |     1 |    39 |  2092K  (1)| 06:58:26 |  1284 |  1284 |  
  13. |*  5 |      INDEX RANGE SCAN                | IDX_VT7_DATETIME   |     1 |       |  6029   (1)| 00:01:13 |  1284 |  1284 |  
  14. |*  6 |    INDEX UNIQUE SCAN                 | PK_ITS_BASE_DEVICE |     1 |       |     0   (0)| 00:00:01 |       |       |  
  15. |*  7 |   TABLE ACCESS BY INDEX ROWID        | ITS_BASE_DEVICE    |     1 |    72 |     0   (0)| 00:00:01 |       |       |  
  16. ---------------------------------------------------------------------------------------------------------------------------  
  17.    
  18. Query Block Name / Object Alias (identified by operation id):  
  19. -------------------------------------------------------------  
  20.    
  21.    1 - SEL$5DA710D3  
  22.    4 - SEL$5DA710D3 / V@SEL$1  
  23.    5 - SEL$5DA710D3 / V@SEL$1  
  24.    6 - SEL$5DA710D3 / ITS_BASE_DEVICE@SEL$2  
  25.    7 - SEL$5DA710D3 / ITS_BASE_DEVICE@SEL$2  
  26.    
  27. Outline Data  
  28. -------------  
  29.    
  30.   /*+  
  31.       BEGIN_OUTLINE_DATA  
  32.       NLJ_BATCHING(@"SEL$5DA710D3" "ITS_BASE_DEVICE"@"SEL$2")  
  33.       USE_NL(@"SEL$5DA710D3" "ITS_BASE_DEVICE"@"SEL$2")  
  34.       LEADING(@"SEL$5DA710D3" "V"@"SEL$1" "ITS_BASE_DEVICE"@"SEL$2")  
  35.       INDEX(@"SEL$5DA710D3" "ITS_BASE_DEVICE"@"SEL$2" ("ITS_BASE_DEVICE"."UNID"))  
  36.       INDEX_RS_ASC(@"SEL$5DA710D3" "V"@"SEL$1" ("ITS_CAR_PASS7"."PASS_DATETIME"))  
  37.       OUTLINE(@"SEL$2")  
  38.       OUTLINE(@"SEL$1")  
  39.       UNNEST(@"SEL$2")  
  40.       OUTLINE_LEAF(@"SEL$5DA710D3")  
  41.       FIRST_ROWS  
  42.       DB_VERSION('11.2.0.3')  
  43.       OPTIMIZER_FEATURES_ENABLE('11.2.0.3')  
  44.       IGNORE_OPTIM_EMBEDDED_HINTS  
  45.       END_OUTLINE_DATA  
  46.   */  
  47.    
  48. Predicate Information (identified by operation id):  
  49. ---------------------------------------------------  
  50.    
  51.    5 - access("PASS_DATETIME">=TO_DATE(' 2013-07-06 17:46:04', 'syyyy-mm-dd hh24:mi:ss') AND   
  52.               "PASS_DATETIME"<=TO_DATE(' 2013-07-06 18:46:06', 'syyyy-mm-dd hh24:mi:ss'))  
  53.    6 - access("V"."PASS_DEVICE_UNID"="UNID")  
  54.    7 - filter("DEV_BAY_UNID"='01685EFE4658C19D59C4DDAAEDD37393' AND "DEV_TYPE"='1' AND "DEV_DELETE_FLAG"='N' AND   
  55.               "DEV_CHK_FLAG"='1')  


 执行计划又变了,我们也先别管执行计划为啥变了,驱动表仍然是 ITS_CAR_PASS7,现在我们来改变驱动表

  1. select /*+ leading(ITS_BASE_DEVICE@SEL$2) */ rowid rid  
  2.    from its_car_pass7 v  
  3.   where 1 = 1  
  4.     and pass_datetime >=  
  5.         to_date('2013-07-06 :17:46:04', 'yyyy-mm-dd hh24:mi:ss')  
  6.     and pass_datetime <=  
  7.         to_date('2013-07-06 :18:46:06', 'yyyy-mm-dd hh24:mi:ss')  
  8.     and v.pass_device_unid in  
  9.         (select unid  
  10.            from its_base_device  
  11.           where dev_bay_unid in ('01685EFE4658C19D59C4DDAAEDD37393')  
  12.             and dev_type = '1'  
  13.             and dev_chk_flag = '1'  
  14.             and dev_delete_flag = 'N')  
  15.   order by v.pass_datetime asc   
  16.  /  
  17.   
  18. Execution Plan  
  19. ----------------------------------------------------------  
  20. Plan hash value: 712001411  
  21.   
  22. -------------------------------------------------------------------------------------------------------------------------------  
  23. | Id  | Operation                          | Name                     | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |  
  24. -------------------------------------------------------------------------------------------------------------------------------  
  25. |   0 | SELECT STATEMENT                   |                          |     1 |   111 |    25   (4)| 00:00:01 |       |       |  
  26. |   1 |  SORT ORDER BY                     |                          |     1 |   111 |    25   (4)| 00:00:01 |       |       |  
  27. |*  2 |   TABLE ACCESS BY LOCAL INDEX ROWID| ITS_CAR_PASS7            |     1 |    39 |     2   (0)| 00:00:01 |  1284 |  1284 |  
  28. |   3 |    NESTED LOOPS                    |                          |     1 |   111 |    24   (0)| 00:00:01 |       |       |  
  29. |*  4 |     TABLE ACCESS BY INDEX ROWID    | ITS_BASE_DEVICE          |     6 |   432 |    12   (0)| 00:00:01 |       |       |  
  30. |*  5 |      INDEX RANGE SCAN              | IDX_DEVICE_DEV_BAY_UNID  |     7 |       |     1   (0)| 00:00:01 |       |       |  
  31. |   6 |     PARTITION RANGE SINGLE         |                          |    44M|       |     2   (0)| 00:00:01 |  1284 |  1284 |  
  32. |*  7 |      INDEX RANGE SCAN              | IDX_VT7_PASS_DEVICE_UNID |    44M|       |     2   (0)| 00:00:01 |  1284 |  1284 |  
  33. -------------------------------------------------------------------------------------------------------------------------------  
  34.   
  35. Predicate Information (identified by operation id):  
  36. ---------------------------------------------------  
  37.   
  38.    2 - filter("PASS_DATETIME">=TO_DATE(' 2013-07-06 17:46:04', 'syyyy-mm-dd hh24:mi:ss') AND  
  39.               "PASS_DATETIME"<=TO_DATE(' 2013-07-06 18:46:06', 'syyyy-mm-dd hh24:mi:ss'))  
  40.    4 - filter("DEV_TYPE"='1' AND "DEV_DELETE_FLAG"='N' AND "DEV_CHK_FLAG"='1')  
  41.    5 - access("DEV_BAY_UNID"='01685EFE4658C19D59C4DDAAEDD37393')  
  42.    7 - access("V"."PASS_DEVICE_UNID"="UNID")  
  43.   
  44.   
  45. Statistics  
  46. ----------------------------------------------------------  
  47.           1  recursive calls  
  48.           0  db block gets  
  49.       18645  consistent gets  
  50.         130  physical reads  
  51.           0  redo size  
  52.       47861  bytes sent via SQL*Net to client  
  53.        1657  bytes received via SQL*Net from client  
  54.         105  SQL*Net roundtrips to/from client  
  55.           1  sorts (memory)  
  56.           0  sorts (disk)  
  57.        1560  rows processed  


驱动表改了之后,逻辑读从11W降低为1.8W 


上一篇:【Java】*开源镜像站汇总


下一篇:anaconda换源