zoukankan      html  css  js  c++  java
  • 转 sql 语句性能比较慢 执行计划

    Dear :

    该条SQL  主要慢在 如下 标黄线的 步骤 ,以下是 如下3表关联

    3张表的总的 数据量在20200902 统计如下:

    d0: 4860

    d1 :581812893

    d2:107189215

    绑定变量值为20200901

    select count(*) from aa.d1 GL  where  GL.RECORD_DATE = '20200901';

      COUNT(*)

    ----------

       1221920

    SQL> select count(*) from aa.d0 where FDATE= '20200901';

      COUNT(*)

    ----------

             2

    SQL>  select count(*) from aa.d2   where FDATE = '20200901';

      COUNT(*)

    ----------

         57968

    当使用 MERGE JOIN CARTESIAN  时候,d1 中( 时间为'20200901' 的数据达到了1221920 )  和  d0( 时间为'20200901' 的数据达到了2 )进行笛卡尔查询,

    没有使用关联条件,导致查询的返回结果 达到2500000 笔数据

      最后在跟d2 (时间为'20200901' 的数据达到了  57968)进行netloop 查询,导致数据库执行SQL 异常增加。

     

    建议如下:

     

    1.d1 表的字段 和 d0 的字段,做一个关联查询,,比如 d1.column_name = d0.column_name

    2.找到更好的执行计划,固定执行计划,

    附录:

    Current Execution Plans (last execution)

    Captured while still in memory. Metrics below are for the last execution of each child cursor.
    If STATISTICS_LEVEL was set to ALL at the time of the hard-parse then A-Rows column is populated.

    Inst: 1   Child: 0    Plan hash value: 3128636944

     

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

                          | Id  | Operation                               | Name                | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | Pstart| Pstop |  OMem |  1Mem | Used-Mem |

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

                          |   0 | INSERT STATEMENT                        |                     |        |       |   494 (100)|          |       |       |       |       |          |

                          |   1 |  LOAD TABLE CONVENTIONAL                |                     |        |       |            |          |       |       |       |       |          |

                          |   2 |   HASH GROUP BY                         |                     |      1 |   200 |   494   (1)| 00:00:06 |       |       |   762K|   762K|          |

                          |   3 |    NESTED LOOPS                         |                     |      1 |   200 |   493   (0)| 00:00:06 |       |       |       |       |          |

                          |   4 |     NESTED LOOPS                        |                     |      1 |   200 |   493   (0)| 00:00:06 |       |       |       |       |          |

                          |   5 |      MERGE JOIN CARTESIAN               |                     |      1 |   162 |   491   (0)| 00:00:06 |       |       |       |       |          |

                          |   6 |       PARTITION LIST SINGLE             |                     |      1 |   114 |     0   (0)|          |   KEY |   KEY |       |       |          |

                          |*  7 |        TABLE ACCESS BY LOCAL INDEX ROWID| d1             |      1 |   114 |     0   (0)|          |   KEY |   KEY |       |       |          |

                          |*  8 |         INDEX RANGE SCAN                | IDX_d1_02      |      1 |       |     0   (0)|          |   KEY |   KEY |       |       |          |

                          |   9 |       BUFFER SORT                       |                     |      2 |    96 |   491   (0)| 00:00:06 |       |       | 73728 | 73728 |          |

                         |* 10 |        TABLE ACCESS FULL                | d0 |      2 |    96 |   491   (0)| 00:00:06 |       |       |       |       |          |

                          |* 11 |      INDEX RANGE SCAN                   | IDX_d2_01 |  49057 |       |     1   (0)| 00:00:01 |       |       |       |       |          |

                          |* 12 |     TABLE ACCESS BY INDEX ROWID         | d2        |      1 |    38 |     2   (0)| 00:00:01 |       |       |       |       |          |

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

     

                          Query Block Name / Object Alias (identified by operation id):

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

     

    SQL Text


    INSERT INTO T096 (DATA_DATE, BRANCH, SEQ_NO, FLAG, PAY_dddd_NO, SHOU_dddd_NO, TRAN_AMT, TRAN_CNT) SELECT :B1 , GH.BRANCH, NULL, DECODE(GRA.IS_INTEREST, 'Y', 'L', 'B') FLAG, GRA.GL_dddd_NO, GRA.BASE_dddd_NO, ABS(SUM(DECODE(GH.REVERSAL, 'Y', DECODE(GH.DR_CR_IND, 'C', ABS(GH.AMOUNT), 'D', -1 * ABS(GH.AMOUNT)), 'N', DECODE(GH.DR_CR_IND, 'D', ABS(GH.AMOUNT), 'C', -1 * ABS(GH.AMOUNT))))), SUM(DECODE(GH.REVERSAL, 'N', 1, 'Y', -1)) CNT FROM d1 GH, d2 GAC, d0 GRA WHERE GH.dddd_INTERNAL_KEY = GAC.INTERNAL_KEY AND GAC.dddd_NO = GRA.GL_dddd_NO AND GH.SOURCE_TYPE = 'LO' AND GH.VALUE_DATE = GH.RECORD_DATE AND GH.RECORD_DATE = :B1 AND GH.FDATE = :B1 AND GAC.FDATE = :B1 AND GRA.FDATE = :B1 GROUP BY GRA.GL_dddd_NO, GH.BRANCH, DECODE(GRA.IS_INTEREST, 'Y', 'L', 'B'), GRA.BASE_dddd_NO

     

     

    --分析过程

    |* 7 | TABLE ACCESS BY LOCAL INDEX ROWID| d1| 1 | 114 | 0 (0)| | KEY | KEY | | | |
    |* 8 | INDEX RANGE SCAN | IDX_GL_HIST_02 | 1 | | 0 (0)| | KEY | KEY | | | |
    | 9 | BUFFER SORT | | 2 | 96 | 491 (0)| 00:00:06 | | | 73728 | 73728 | |
    |* 10 | TABLE ACCESS FULL | d0 | 2 | 96 | 491 (0)| 00:00:06 | | | | |


    7 - filter(("GH"."VALUE_DATE"=:B1 AND "GH"."RECORD_DATE"=:B1))
    8 - access("GH"."FDATE"=:B1 AND "GH"."SOURCE_TYPE"='LO')
    filter("GH"."SOURCE_TYPE"='LO')

    10 - filter("GRA"."FDATE"=:B1)


    d0: 4860

    d1:581812893

    d2:107189215

    select count(*) from aa.d0;
    select count(*) from aa.GL_HIST;
    select count(*) from aa.d2;


    select count(*) from aa.d1;

    COUNT(*)
    ----------
    595877133

    SQL> select count(*) from aa.d2;

    COUNT(*)
    ----------
    107155579

    SQL>
    select count(*) from aa.d0;
    COUNT(*)
    ----------
    4952


    select count(*) from aa.d1GL where GL.RECORD_DATE = '20200901';

    COUNT(*)
    ----------
    1221920

    SQL> select count(*) from aa.d0 where FDATE= '20200901';

    COUNT(*)
    ----------
    2


    SQL> select count(*) from aa.d2 where FDATE = '20200901';

    COUNT(*)
    ----------
    57968

    SQL Text
    --------------------------------------------------------------------------------

    INSERT INTO TP_B_user096 (DATA_DATE, BRANCH, SEQ_NO, FLAG, PAY_dddd_NO, SHOU_dddd_NO, TRAN_AMT, TRAN_CNT) SELECT :B1 , GH.BRANCH, NULL, DECODE(GRA.IS_INTEREST, 'Y', 'L', 'B') FLAG, GRA.GL_dddd_NO, GRA.BASE_dddd_NO, ABS(SUM(DECODE(GH.REVERSAL, 'Y', DECODE(GH.DR_CR_IND, 'C', ABS(GH.AMOUNT), 'D', -1 * ABS(GH.AMOUNT)), 'N', DECODE(GH.DR_CR_IND, 'D', ABS(GH.AMOUNT), 'C', -1 * ABS(GH.AMOUNT))))), SUM(DECODE(GH.REVERSAL, 'N', 1, 'Y', -1)) CNT FROM d1GH, d2 GAC, d0 GRA WHERE GH.dddd_INTERNAL_KEY = GAC.INTERNAL_KEY AND GAC.dddd_NO = GRA.GL_dddd_NO AND GH.SOURCE_TYPE = 'LO' AND GH.VALUE_DATE = GH.RECORD_DATE AND GH.RECORD_DATE = :B1 AND GH.FDATE = :B1 AND GAC.FDATE = :B1 AND GRA.FDATE = :B1 GROUP BY GRA.GL_dddd_NO, GH.BRANCH, DECODE(GRA.IS_INTEREST, 'Y', 'L', 'B'), GRA.BASE_dddd_NO


    假设绑定变量值为20200901

    SQL> select count(*) from aa.d1GL w here GL.RECORD_DATE = '20200901';

    COUNT(*)
    ----------
    1221920


    ##查看正在执行的SQL 绑定变量值,
    ###https://www.cnblogs.com/kerrycode/p/7476443.html

    sql_id:dp7mzr2kg3c4z

    SELECT
    b.sql_id,
    t.sql_text sql_text,
    b.name bind_name,
    b.value_string bind_value
    FROM
    v$sql t
    JOIN
    v$sql_bind_capture b on t.hash_value = b.hash_value and t.child_address = b.child_address
    WHERE
    b.value_string is not null
    AND
    b.sql_id='&sqlid'


    SQL> COL NAME FOR A12;
    SQL> COL DATATYPE_STRING FOR A24;
    SQL> COL VALUE_STRING FOR A32;
    SQL> SELECT NAME,
    2 DATATYPE_STRING,
    3 VALUE_STRING,
    4 MAX_LENGTH,
    5 LAST_CAPTURED
    6 FROM V$SQL_BIND_CAPTURE
    7 WHERE SQL_ID = '1t2r2p48W4P0g';

    后记:

    --因为是insert 慢,后继  开发反馈单独select 查询很快,于是单独拿出select 看了看

    发现走的快的执行计划还是跟慢的执行计划不一样,一个用的是IDX_GL_ACCT_CORE_02。一个用的是IDX_GL_ACCT_CORE_01

    Plan hash value: 4260575868

    ---------------------------------------------------------------------------------------------------------------------------------------------------
    | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem |

    PLAN_TABLE_OUTPUT
    ------------------------------------------------------------------------------------------------------------------------------------------------------
    ---------------------------------------------------------------------------------------------------------------------------------------------------
    | 0 | SELECT STATEMENT | | 1 | | 0 |00:00:02.33 | 683K| | | |
    | 1 | HASH GROUP BY | | 1 | 1 | 0 |00:00:02.33 | 683K| 762K| 762K| |
    | 2 | NESTED LOOPS | | 1 | 1 | 0 |00:00:02.33 | 683K| | | |
    | 3 | NESTED LOOPS | | 1 | 1 | 619K|00:00:02.50 | 64200 | | | |
    | 4 | MERGE JOIN CARTESIAN | | 1 | 1 | 619K|00:00:01.57 | 64182 | | | |
    | 5 | PARTITION LIST SINGLE | | 1 | 1 | 309K|00:00:00.62 | 63303 | | | |
    |* 6 | TABLE ACCESS BY LOCAL INDEX ROWID| GL_HIST | 1 | 1 | 309K|00:00:00.58 | 63303 | | | |
    |* 7 | INDEX RANGE SCAN | IDX_GL_HIST_02 | 1 | 1 | 309K|00:00:00.18 | 9536 | | | |
    | 8 | BUFFER SORT | | 309K| 2 | 619K|00:00:00.14 | 879 | 2048 | 2048 | 2048 (0)|
    |* 9 | TABLE ACCESS FULL | GL_RB_ACCT_TRANSFER | 1 | 2 | 2 |00:00:00.01 | 879 | | | |

    PLAN_TABLE_OUTPUT
    ------------------------------------------------------------------------------------------------------------------------------------------------------
    |* 10 | INDEX RANGE SCAN | IDX_GL_ACCT_CORE_02 | 619K| 1 | 619K|00:00:00.73 | 18 | | | |                                                 《-  这里走的是IDX_GL_ACCT_CORE_02
    |* 11 | TABLE ACCESS BY INDEX ROWID | GL_ACCT_CORE | 619K| 1 | 0 |00:00:00.49 | 619K| | | |
    ---------------------------------------------------------------------------------------------------------------------------------------------------

    验证如下: 强制走 索引 IDX_GL_ACCT_CORE_01 很慢

    SELECT /*+ INDEX (GAC IDX_GL_ACCT_CORE_01 )*/
    '20200902',
    GH.BRANCH,
    NULL,
    DECODE(GRA.IS_INTEREST, 'Y', 'L', 'B') FLAG,
    GRA.GL_ACCT_NO,

    强制走索引 IDX_GL_ACCT_CORE_02  很快, 

    SELECT /*+ INDEX (GAC IDX_GL_ACCT_CORE_02 )*/
    '20200902',
    GH.BRANCH,

    这也给我们调优提供了一个思路,强制走索引 IDX_GL_ACCT_CORE_02   也是一条优化建议。 

    通过这个案例,感觉到O 记的自适应性,和社区的强大。这一点远远超过 开源数据库 社区。

  • 相关阅读:
    十大排序算法总结
    Java Web之监听器
    JVM 内存模型
    设计模式--装饰者模式和建造者模式
    Java Web之过滤器
    jsp-servlet篇(三)
    jsp- servlet篇(二)
    jsp- servlet篇(一)
    xml和xml解析
    k8s环境部署(一)
  • 原文地址:https://www.cnblogs.com/feiyun8616/p/13600673.html
Copyright © 2011-2022 走看看