zoukankan      html  css  js  c++  java
  • 标量子查询优化(用group by 代替distinct)

    标量子查询优化 
    
    当使用另外一个SELECT 语句来产生结果中的一列的值的时候,这个查询必须只能返回一行一列的值。这种类型的子查询被称为标量子查询
    
    在某些情况下可以进行优化以减少标量子查询的重复执行,但更糟糕的场景是每一行都需要标量子查询的执行。
    
    
    explain plan for SELECT B.EMP_NO,
           B.CUST_NO,
           B.CUST_NAME,
           A.CARD_NO,
           A.TRANS_AMT,
           A.TRANS_ATTR,
           /*(0 ?? 1 鲁盲 2 鲁盲?禄?4 ??)*/
           A.TRANS_TIME,
           A.SEQNO,
           A.OLD_TRANSDATE
      FROM (SELECT * FROM DWF.F_EVT_REAL_JOURLIST WHERE TRANS_TYPE = '00') A
      LEFT JOIN (SELECT AGMT_ID,
                        CUST_MAGR EMP_NO,
                        CUST_NO,
                        (SELECT DISTINCT PTY_NAME
                           FROM DWF.F_PTY_TABLE
                          WHERE PTY_ID = A.CUST_NO
                            AND START_DT <= TO_DATE('2012-09-30', 'YYYY-MM-DD')
                            AND END_DT > TO_DATE('2012-09-30', 'YYYY-MM-DD')) CUST_NAME
                   FROM DWF.F_AGT_CADB_BOOK_H A
                  WHERE START_DT <= TO_DATE('2012-09-30', 'YYYY-MM-DD')
                    AND END_DT > TO_DATE('2012-09-30', 'YYYY-MM-DD')) B ON A.CARD_NO =
                                                                           B.AGMT_ID;
    --220109
    
    SELECT AGMT_ID,
                        CUST_MAGR EMP_NO,
                        CUST_NO,
                        (SELECT DISTINCT PTY_NAME
                           FROM DWF.F_PTY_TABLE
                          WHERE PTY_ID = A.CUST_NO
                            AND START_DT <= TO_DATE('2012-09-30', 'YYYY-MM-DD')
                            AND END_DT > TO_DATE('2012-09-30', 'YYYY-MM-DD')) CUST_NAME
                   FROM DWF.F_AGT_CADB_BOOK_H A
                  WHERE START_DT <= TO_DATE('2012-09-30', 'YYYY-MM-DD')
                    AND END_DT > TO_DATE('2012-09-30', 'YYYY-MM-DD')
    查询返回了204947条记录
     
    
    ###########################################################################################################################
    Plan hash value: 579615344
    
    ---------------------------------------------------------------------------------------------------------------------------------------------
    | Id  | Operation		         | Name		         | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads  |  OMem |  1Mem | Used-Mem |
    ---------------------------------------------------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT	         |			 |	1 |	     |	  220K|00:00:12.12 |	 781K|	  280K|       |       |       |
    |   1 |  SORT UNIQUE		         |			 |155K    |	   1 |	  155K|00:00:06.52 |	 501K|	 2882 |  2048 |  2048 | 2048  (0)|
    |*  2 |   TABLE ACCESS BY INDEX ROWID    | F_PTY_TABLE	         |155K    |	   1 |	  155K|00:00:05.41 |	 501K|	 2882 |       |       |       |
    |*  3 |    INDEX RANGE SCAN	         | SYS_C0052731	         |155K    |	   1 |	  188K|00:00:04.17 |	 313K|	  448 |       |       |       |
    |*  4 |  HASH JOIN OUTER	         |			 |      1 |	1399K|	  220K|00:00:12.12 |	 781K|	  280K|    20M|  2674K|   25M (0)|
    |*  5 |   TABLE ACCESS FULL	         | F_EVT_REAL_JOURLIST   |  1     |	 145K|	  220K|00:00:00.08 |	7904 |	 7900 |       |       |       |
    |   6 |   VIEW			         |			 |      1 |	3929K|	  204K|00:00:11.54 |	 773K|	  272K|       |       |       |
    |*  7 |    TABLE ACCESS FULL	         | F_AGT_CADB_BOOK_H     |      1 |	3929K|	  204K|00:00:04.68 |	 272K|	  270K|       |       |       |
    --------------------------------------------------------------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       2 - filter("END_DT">TO_DATE(' 2012-09-30 00:00:00', 'syyyy-mm-dd hh24:mi:ss'))
       3 - access("PTY_ID"=:B1 AND "START_DT"<=TO_DATE(' 2012-09-30 00:00:00', 'syyyy-mm-dd hh24:mi:ss'))
           filter("START_DT"<=TO_DATE(' 2012-09-30 00:00:00', 'syyyy-mm-dd hh24:mi:ss'))
       4 - access("F_EVT_REAL_JOURLIST"."CARD_NO"="B"."AGMT_ID")
       5 - filter("TRANS_TYPE"='00')
       7 - filter(("START_DT"<=TO_DATE(' 2012-09-30 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "END_DT">TO_DATE(' 2012-09-30 00:00:00',
    	      'syyyy-mm-dd hh24:mi:ss')))
    
    
    43 rows selected.
    此时对F_PTY_TABLE索引扫描了155K次,回表了155K次 这种效率能高吗?
    改写为关联
    ###########################################################################################
    SELECT b.emp_no,
           b.cust_no,
           b.cust_name,
           a.card_no,
           a.trans_amt,
           a.trans_attr,
           a.trans_time,
           a.seqno,
           a.old_transdate
      FROM (SELECT * FROM dwf.f_evt_real_jourlist WHERE trans_type = '00') a
      LEFT JOIN (SELECT agmt_id,
                        cust_magr    emp_no,
                        cust_no,
                        c_n.pty_name AS cust_name
                   FROM dwf.f_agt_cadb_book_h a
                   LEFT JOIN (SELECT pty_name, pty_id
                               FROM dwf.f_pty_table
                              WHERE start_dt <=
                                    to_date('2012-09-30', 'YYYY-MM-DD')
                                AND end_dt > to_date('2012-09-30', 'YYYY-MM-DD')
                              GROUP BY pty_name, pty_id) c_n
                     ON c_n.pty_id = a.cust_no
                  WHERE start_dt <= to_date('2012-09-30', 'YYYY-MM-DD')
                    AND end_dt > to_date('2012-09-30', 'YYYY-MM-DD')) b
        ON a.card_no = b.agmt_id;
     
    
    这里巧妙的运用了group by 来去除重复数据,像伟大的教主致敬.
    
    


     

  • 相关阅读:
    OpenShift和F5的集成手册
    OpenShift负载分区策略(Router Shading)
    Istio在Openshift 3.11的安装
    Openshift 和Harbor的集成
    OpenShift 如何获取bearer Token以便进行各种API调用
    Openshift 3.11和LDAP的集成
    Openshift 节点添加和删除
    Spring Dataflow批处理框架在OCP上的部署
    Openshift 用户,角色和RBAC
    取消Windows server 关机提示备注的方法
  • 原文地址:https://www.cnblogs.com/zhaoyangjian724/p/3798107.html
Copyright © 2011-2022 走看看