oracle 11g亿级复杂SQL优化一例(数量级性能提升)

Posted 太白的技术博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了oracle 11g亿级复杂SQL优化一例(数量级性能提升)相关的知识,希望对你有一定的参考价值。

自从16年之后,因为工作原因,项目中就没有再使用oracle了,最近最近支持一个项目,又要开始负责这块事情了。最近在跑性能测试,配置全部调好之后,不少sql还存在性能低下的问题,主要涉及执行计划的不合理,以及相关pga隐含参数的优化。可能因为几年不接触的原因,略微有些生疏需要review了。这里以最近优化过的某个比较典型的例子为例(这里只讲思路、因为涉及到敏感信息,不给出最终结果,16C E5620@2.40GHz/45GB内存/fio 85/15 iops 8500/1500 配置,优化前100G临时空间都爆掉,到20分钟出结果,实际上允许完全调整的话,最多5分钟就可以运行出来),这个例子比较经典,它是一个产品转换的例子,从业务逻辑上来看,它需要对两个100w(100管理人*1w支产品)记录的结果集进行黑名单(是指A产品->B产品是否允许转换,A->B不允许,不意味着B->A不允许)以外的笛卡尔积关联,,重点回顾下一些重要的operation以及如何通过hint强制,子查询独立运行时的operation和作为主查询的子查询运行时的operation不相同可能会造成性能差异巨大。首先,不要指望写一段sql,既可以在oracle下运行、也可以在mysql下运行。原始的sql语句以及执行计划如下:

INSERT INTO C3(
                   tenantid,c_code,l_serialno,c_txtfundcode,
                   c_chargetype,f_sharemin,f_sharemax,l_hold,c_txtothercode,
                   c_targetchargetype,c_custtype,c_flag,d_operatedate,d_cdate,c_cyno)
            SELECT a.tenantid,a.c_code,l_serialno,
                   CASE a.agencytypes WHEN \'AB\' THEN a.c_prdcode ELSE COALESCE(b.c_outprdcode,a.c_prdcode) END c_txtfundcode,
                   c_chargetype,f_sharemin,f_sharemax,l_hold,
                   CASE a.agencytypes WHEN \'AB\'THEN a.c_othercode ELSE COALESCE(c.c_outprdcode,a.c_othercode) END c_txtothercode,
                   c_targetchargetype,c_custtype,c_flag,d_operatedate,20100511 d_cdate,a.c_cyno
              FROM (SELECT 0 l_serialno,
                           CASE t.c_mutextype WHEN \'A\' THEN \'0\' WHEN \'B\' THEN \'1\' WHEN \'C\' THEN \'2\' ELSE t.c_mutextype END c_chargetype,
                           CASE t.c_targetsharetype WHEN \'A\' THEN \'0\' WHEN \'B\' THEN \'1\' WHEN \'C\' THEN \'2\' ELSE t.c_targetsharetype END c_targetchargetype,
                           ar.f_cminmutex f_sharemin,99999999999999.9 f_sharemax,0 l_hold,\'2\' c_custtype,
                           \'1\' c_flag,\'20000101\' d_operatedate,
                           t.*
                      FROM (SELECT fo.tenantid, fo.c_code, fo.c_prdcode,fi.c_prdcode c_othercode,
                                   fo.c_cyno,fo.c_mutextype,fi.c_mutextype c_targetsharetype,
                                   fo.d_contractdate d_contractdate, fo.c_mutextypes c_mutextypes,
                                   fo.agencytypes,
                                   fi.d_contractdate d_othercontractdate, fi.c_mutextypes c_othersharetypes
                              FROM (SELECT DISTINCT ss.tenantid, ss.c_code, ss.c_prdcode,
                                                    ss.c_cyno,ss.c_mutextype c_mutextype,
                                                    ta.c_mutextypes agencytypes,
                                                    getsysvalue(ss.tenantid, ss.c_code, ss.c_cyno,ss.c_managercode, ss.c_prdcode,\'ContractDate\', \'20991231\') d_contractdate,
                                                    getsysvalue(ss.tenantid, ss.c_code, ss.c_cyno,ss.c_managercode, ss.c_prdcode,\'ShareTypes\', \'\') c_mutextypes
                                      FROM (SELECT fi.tenantid, fi.c_code, fi.c_prdcode,c.c_cyno,
                                                   s.c_mutextype, fi.c_managercode
                                              FROM FUNDINFO fi,
                                                   (SELECT \'A\' c_mutextype FROM DUAL
                                                     UNION ALL
                                                    SELECT \'B\' c_mutextype FROM DUAL
                                                     UNION ALL
                                                    SELECT \'C\' c_mutextype FROM DUAL) s,
                                                   QUALIFY c,
                                                   EXPBATCH d
                                             WHERE fi.c_code   = \'F6\'
                                               AND fi.tenantid = \'*\'
                                               AND fi.c_fundstatus NOT IN (\'6\', \'9\')
                                               AND c.c_code    = \'F6\'
                                               AND c.tenantid  = \'*\'
                                               AND c.c_cyno  = d.c_cyno
                                               AND c.c_code    = d.c_code
                                               AND c.tenantid  = d.tenantid
                                               AND INSTR(fi.c_mutextypes, s.c_mutextype) > 0
                                               AND (fi.c_fundtype<>\'1\'
                                                   OR
                                                   NOT EXISTS(SELECT 1 FROM TEXT_PARAMETER
                                                               WHERE c_paramitem  = \'ChangeLimit\'
                                                                 AND c_paramvalue = \'1\'
                                                                 AND c_prdcode   = fi.c_prdcode
                                                                 AND c_code     = \'F6\'
                                                                 AND tenantid   = \'*\'))
                                               AND fi.c_prdcode  = c.c_prdcode
                                               AND c.c_issaleflag = \'1\'
                                           ) ss,
                                           EXPBATCH ta
                                     WHERE ss.c_cyno = ta.c_cyno
                                       AND ss.c_code   = ta.c_code
                                       AND ss.tenantid = ta.tenantid
                                       AND ta.c_notexpparamfiles = \'0\'
                                   ) fo,
                                   (SELECT DISTINCT ss.tenantid, ss.c_code, ss.c_prdcode,
                                                    ss.c_cyno,ss.c_mutextype c_mutextype,
                                                    getsysvalue(ss.tenantid, ss.c_code, ss.c_cyno,ss.c_managercode, ss.c_prdcode,\'ContractDate\', 20991231) d_contractdate,
                                                    getsysvalue(ss.tenantid, ss.c_code, ss.c_cyno,ss.c_managercode, ss.c_prdcode,\'ShareTypes\', \'\') c_mutextypes
                                      FROM (SELECT fi.tenantid, fi.c_code, fi.c_prdcode,
                                                   c.c_cyno, s.c_mutextype, fi.c_managercode
                                              FROM FUNDINFO fi,
                                                   (SELECT \'A\' c_mutextype FROM DUAL
                                                     UNION ALL
                                                    SELECT \'B\' c_mutextype FROM DUAL
                                                     UNION ALL
                                                    SELECT \'C\' c_mutextype FROM DUAL) s,
                                                   QUALIFY c,
                                                   EXPBATCH d
                                             WHERE fi.c_code   = \'F6\'
                                               AND fi.tenantid = \'*\'
                                               AND c.c_code    = \'F6\'
                                               AND c.tenantid  = \'*\'
                                               AND c.c_cyno  = d.c_cyno
                                               AND c.c_code    = d.c_code
                                               AND c.tenantid  = d.tenantid
                                               AND INSTR(fi.c_mutextypes, s.c_mutextype) > 0
                                               AND fi.c_fundstatus NOT IN (\'6\', \'9\')
                                               AND (fi.c_fundtype <> \'1\'
                                                   OR NOT EXISTS
                                                   (SELECT 1 FROM TEXT_PARAMETER
                                                     WHERE c_paramitem  = \'ChangeLimit\'
                                                       AND c_paramvalue = \'1\'
                                                       AND c_prdcode   = fi.c_prdcode
                                                       AND c_code     = \'F6\'
                                                       AND tenantid   = \'*\'))
                                               AND fi.c_prdcode  = c.c_prdcode
                                               AND c.c_issaleflag = \'1\'
                                           ) ss,
                                           EXPBATCH ta
                                     WHERE ss.c_cyno = ta.c_cyno
                                       AND ss.c_code   = ta.c_code
                                       AND ss.tenantid = ta.tenantid
                                       AND ta.c_notexpparamfiles = \'0\'
                                   ) fi
                             WHERE fo.c_prdcode <> fi.c_prdcode
                               AND fo.c_mutextype = fi.c_mutextype
                               AND fo.c_cyno  = fi.c_cyno
                           ) t,(SELECT c_prdcode, c_cyno, MIN(a.f_cminmutex) f_cminmutex
                                  FROM ARLIMIT a
                                 WHERE c_cyno <> \'*\'
                                   AND c_code = \'F6\'
                                   AND tenantid = \'*\'
                                 GROUP BY c_prdcode, c_cyno
                                UNION ALL
                                SELECT c_prdcode, b.c_cyno, MIN(f_cminmutex) f_cminmutex
                                  FROM ARLIMIT a, EXPBATCH b
                                 WHERE a.c_cyno = \'*\'
                                   AND a.c_code = \'F6\'
                                   AND a.tenantid = \'*\'
                                   AND a.c_code = b.c_code
                                   AND a.tenantid = b.tenantid
                                   AND not exists (SELECT 1
                                                      FROM ARLIMIT c
                                                     WHERE b.c_cyno = c.c_cyno
                                                       AND a.c_prdcode = c.c_prdcode
                                                       AND a.c_code = c.c_code
                                                       AND a.tenantid = c.tenantid)
                                 GROUP BY c_prdcode, b.c_cyno) ar
                     WHERE t.d_contractdate <= 20100511
                       AND t.d_othercontractdate <= 20100511
                       AND INSTR(t.c_mutextypes, t.c_mutextype) > 0
                       AND INSTR(t.c_othersharetypes, t.c_targetsharetype) > 0
                       AND t.c_prdcode = ar.c_prdcode
                       AND t.c_cyno = ar.c_cyno
                       AND NOT EXISTS
                           (SELECT 1
                              FROM CHANGELIMIT b
                             WHERE t.c_prdcode         = b.c_prdcode
                               AND (t.c_mutextype       = b.c_mutextype  OR b.c_mutextype  = \'*\')
                               AND (t.c_cyno        = b.c_cyno   OR b.c_cyno   = \'*\')
                               AND (t.c_othercode       = b.c_othercode  OR b.c_othercode  = \'*\')
                               AND (t.c_targetsharetype = b.c_othershare OR b.c_othershare = \'*\')
                           )
                   ) a
                   LEFT JOIN FUNDCODECHANGE b
                          ON (a.c_prdcode  = b.c_prdcode
                         AND  a.c_mutextype = b.c_mutextype
                         AND  a.c_code    = b.c_code
                         AND  a.tenantid  = b.tenantid)
                   LEFT JOIN FUNDCODECHANGE c
                          ON (a.c_othercode = c.c_prdcode
                         AND  a.c_targetsharetype = c.c_mutextype
                         AND  a.c_code    = c.c_code
                         AND  a.tenantid  = c.tenantid)

 

 

 

-- 此处隐藏了谓词部分
 Plan Hash Value  : 4256998962 

--------------------------------------------------------------------------------------------------------------------------
| Id   | Operation                                   | Name                      | Rows    | Bytes     | Cost | Time     |
--------------------------------------------------------------------------------------------------------------------------
|    0 | INSERT STATEMENT                            |                           |       1 |       129 | 2103 | 00:00:26 |
|    1 |   LOAD TABLE CONVENTIONAL                   | C3                        |         |           |      |          |
|    2 |    NESTED LOOPS OUTER                       |                           |       1 |       129 | 2103 | 00:00:26 |
|    3 |     VIEW                                    |                           |       1 |        95 | 2102 | 00:00:26 |
|  * 4 |      FILTER                                 |                           |         |           |      |          |
|  * 5 |       HASH JOIN                             |                           |       1 |      8105 | 2101 | 00:00:26 |
|  * 6 |        HASH JOIN                            |                           |       1 |      8078 | 1827 | 00:00:22 |
|    7 |         NESTED LOOPS OUTER                  |                           |       1 |      4060 |  914 | 00:00:11 |
|    8 |          VIEW                               |                           |       1 |      4026 |  913 | 00:00:11 |
|    9 |           SORT UNIQUE                       |                           |       1 |        72 |  913 | 00:00:11 |
| * 10 |            FILTER                           |                           |         |           |      |          |
|   11 |             NESTED LOOPS                    |                           |       1 |        72 |  912 | 00:00:11 |
|   12 |              NESTED LOOPS                   |                           |       1 |        72 |  912 | 00:00:11 |
|   13 |               NESTED LOOPS                  |                           |       1 |        58 |  911 | 00:00:11 |
|   14 |                NESTED LOOPS                 |                           |       1 |        49 |  910 | 00:00:11 |
|   15 |                 NESTED LOOPS                |                           |    1500 |     46500 |  309 | 00:00:04 |
|   16 |                  VIEW                       |                           |       3 |         9 |    6 | 00:00:01 |
|   17 |                   UNION-ALL                 |                           |         |           |      |          |
|   18 |                    FAST DUAL                |                           |       1 |           |    2 | 00:00:01 |
|   19 |                    FAST DUAL                |                           |       1 |           |    2 | 00:00:01 |
|   20 |                    FAST DUAL                |                           |       1 |           |    2 | 00:00:01 |
| * 21 |                  TABLE ACCESS FULL          | FUNDINFO              |     500 |     14000 |  101 | 00:00:02 |
| * 22 |                 TABLE ACCESS BY INDEX ROWID | QUALIFY           |       1 |        18 |    1 | 00:00:01 |
| * 23 |                  INDEX RANGE SCAN           | UIDX_QUALIFY         |       1 |           |    1 | 00:00:01 |
| * 24 |                INDEX RANGE SCAN             | PK_BATCH         |       1 |         9 |    oracle11g中SQL优化(SQL TUNING)新特性之SQL Plan Management(SPM)

oracle11g中SQL优化(SQL TUNING)新特性之Adaptive Cursor Sharing (ACS)

Oracle 11g 新特性 -- SQL Plan Management 说明

oracle11g自动维护任务

Oracle 碎片 优化 一例

Oracle AWR性能优化一例