巧妙的用IN替代关联后去从

<pre name="code" class="sql">SQL> explain plan for SELECT DISTINCT d.sender_id,
  2   d.misc_notes,
  3   TO_CHAR(d.creation_date, :"SYS_B_0") creation_date,
  4   d.message
  5   FROM lead l,
  6   lead_document d
  7   WHERE l.email = :1
  8   AND l.lead_id = d.lead_id
  9   AND d.document_type =:"SYS_B_1"
 10   AND d.creation_date > (sysdate - :"SYS_B_2")
 11   ORDER BY d.misc_notes
 12   ;

Explained.

SQL> select * from table(dbms_xplan.display)
  2  ;

PLAN_TABLE_OUTPUT                                                                                                                                                                 

                      
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

-----------------------
Plan hash value: 1890182354                                                                                                                                                       

                      
                                                                                                                                                                                  

                      
------------------------------------------------------------------------------------------------                                                                                  

                      
| Id  | Operation                      | Name          | Rows  | Bytes | Cost (%CPU)| Time     |                                                                                  

                      
------------------------------------------------------------------------------------------------                                                                                  

                      
|   0 | SELECT STATEMENT               |               |     1 |   161 |     9  (23)| 00:00:01 |                                                                                  

                      
|   1 |  SORT UNIQUE                   |               |     1 |   161 |     8  (13)| 00:00:01 |                                                                                  

                      
|   2 |   NESTED LOOPS                 |               |     1 |   161 |     7   (0)| 00:00:01 |                                                                                  

                      
|   3 |    NESTED LOOPS                |               |     1 |   161 |     7   (0)| 00:00:01 |                                                                                  

                      
|   4 |     TABLE ACCESS BY INDEX ROWID| LEAD          |     1 |    46 |     4   (0)| 00:00:01 |                                                                                  

                      
|*  5 |      INDEX RANGE SCAN          | XIE1_LD       |     1 |       |     3   (0)| 00:00:01 |                                                                                  

                      
|*  6 |     INDEX RANGE SCAN           | XIE2_LD_DCMNT |     1 |       |     2   (0)| 00:00:01 |                                                                                  

                      
|*  7 |    TABLE ACCESS BY INDEX ROWID | LEAD_DOCUMENT |     1 |   115 |     3   (0)| 00:00:01 |                                                                                  

                      
------------------------------------------------------------------------------------------------                                                                                  

                      
                                                                                                                                                                                  

                      
Predicate Information (identified by operation id):                                                                                                                               

                      
---------------------------------------------------                                                                                                                               

                      
                                                                                                                                                                                  

                      
   5 - access("L"."EMAIL"=:1)                                                                                                                                                     

                      
   6 - access("L"."LEAD_ID"="D"."LEAD_ID" AND "D"."CREATION_DATE">SYSDATE@!-:SYS_B_2                                                                                              

                      
              AND "D"."CREATION_DATE" IS NOT NULL)                                                                                                                                

                      
   7 - filter("D"."DOCUMENT_TYPE"=:SYS_B_1)                                                                                                                                       

                      

22 rows selected.



关联后带distinct的 如果只从一个表返回记录,那么就可以尝试的改为in,如果从多个表返回记录那就无法改了。

当你看到SQL是inner join,并且用了distinct,并且只从一个表中取数据,可以将这类SQL改写为半连接,避免distinct排序,提升性能

SELECT DISTINCT d.sender_id,
                d.misc_notes,
                TO_CHAR(d.creation_date, :"SYS_B_0") creation_date,
                d.message
  FROM lead l, lead_document d
 WHERE l.email = :1
   AND l.lead_id = d.lead_id
   AND d.document_type = :"SYS_B_1"
   AND d.creation_date > (sysdate - :"SYS_B_2")
l.email = :1
  ORDER BY d.misc_notes

 select d.sender_id,
                d.misc_notes,
                TO_CHAR(d.creation_date, :"SYS_B_0") creation_date,
                d.message
 lead_document d
 where  d.document_type = :"SYS_B_1"
   AND d.creation_date > (sysdate - :"SYS_B_2")
   and d.lead_id in (select l.lead_id  from lead l
   where l.email = :1)
   l.email = :1
    ORDER BY d.misc_notes


SQL> explain plan for select d.sender_id,
  2                  d.misc_notes,
  3                  TO_CHAR(d.creation_date, :"SYS_B_0") creation_date,
  4                  d.message
  5   from lead_document d
  6   where  d.document_type = :"SYS_B_1"
  7     AND d.creation_date > (sysdate - :"SYS_B_2")
  8     and d.lead_id in (select l.lead_id  from lead l
  9     where l.email = :1)
    ORDER BY d.misc_notes
 10   11  ;

Explained.
SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

-----------------------
Plan hash value: 232104937

------------------------------------------------------------------------------------------------
| Id  | Operation                      | Name          | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |               |     1 |   161 |     8  (13)| 00:00:01 |
|   1 |  SORT ORDER BY                 |               |     1 |   161 |     8  (13)| 00:00:01 |
|   2 |   NESTED LOOPS                 |               |     1 |   161 |     7   (0)| 00:00:01 |
|   3 |    NESTED LOOPS                |               |     1 |   161 |     7   (0)| 00:00:01 |
|   4 |     TABLE ACCESS BY INDEX ROWID| LEAD          |     1 |    46 |     4   (0)| 00:00:01 |
|*  5 |      INDEX RANGE SCAN          | XIE1_LD       |     1 |       |     3   (0)| 00:00:01 |
|*  6 |     INDEX RANGE SCAN           | XIE2_LD_DCMNT |     1 |       |     2   (0)| 00:00:01 |
|*  7 |    TABLE ACCESS BY INDEX ROWID | LEAD_DOCUMENT |     1 |   115 |     3   (0)| 00:00:01 |
------------------------------------------------------------------------------------------------

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

   5 - access("L"."EMAIL"=:1)
   6 - access("D"."LEAD_ID"="L"."LEAD_ID" AND "D"."CREATION_DATE">SYSDATE@!-:SYS_B_2
              AND "D"."CREATION_DATE" IS NOT NULL)
   7 - filter("D"."DOCUMENT_TYPE"=:SYS_B_1)

22 rows selected.




                                    
原文地址:https://www.cnblogs.com/hzcya1995/p/13352215.html