Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle 优化PL/SQL代码_Oracle_Plsql_Oracle10g_Query Optimization - Fatal编程技术网

Oracle 优化PL/SQL代码

Oracle 优化PL/SQL代码,oracle,plsql,oracle10g,query-optimization,Oracle,Plsql,Oracle10g,Query Optimization,我知道在没有规范的情况下很难对代码进行优化,但我也没有规范。有人能在下面的代码中进行一些优化吗?因为此代码执行时间超过6天,但我们需要在6或8小时内运行它。有什么建议吗 PROCEDURE kzt_2_27_p ( p_start_date DATE, p_end_date DATE ) AS CURSOR cur1 IS SELECT cal.id, cal.dt, cal.id

我知道在没有规范的情况下很难对代码进行优化,但我也没有规范。有人能在下面的代码中进行一些优化吗?因为此代码执行时间超过6天,但我们需要在6或8小时内运行它。有什么建议吗

PROCEDURE kzt_2_27_p ( p_start_date DATE, p_end_date DATE )
AS
    CURSOR cur1
        IS
            SELECT cal.id,
                 cal.dt,
                 cal.id_period,
                 per.period_name
            FROM xxkkbi_dim_calendar cal,
                 xxkkbi_dim_period per
            WHERE 
                ( cal.dt BETWEEN p_start_date AND p_end_date ) 
            AND 
                per.id = cal.id_period
            ORDER BY cal.dt;

    row1            cur1%ROWTYPE;
    l_year_sum      NUMBER;
    l_id_specific   NUMBER;
    l_region        VARCHAR2 ( 10 CHAR );
    l_period_name   VARCHAR2 ( 10 CHAR );
    l_id_region     NUMBER;
    l_id_date       NUMBER;
    l_id_period     NUMBER;
    l_segment4      VARCHAR2 ( 30 CHAR );
    --------- For Log -------------------------------
    l_fct           VARCHAR2 ( 20 ) := 'FCT_2_27';
    l_date          DATE;
    l_descr         VARCHAR2 ( 2000 CHAR ) := '';
    l_err_code      VARCHAR2 ( 20 CHAR );
    l_err_msg       VARCHAR2 ( 2000 CHAR );
--------- End For Log ----------------------------
BEGIN
    pkg_fct_log.fct_log_2 ( p_fct_name  => l_fct, p_oper_name => 'START PROCEDURE' );

    FOR row1 IN cur1
    LOOP
        l_date := row1.dt;
        l_period_name := row1.period_name;
        l_id_period := row1.id_period;
        l_id_date := row1.id;

        DELETE FROM xxkkbi.fct_2_27 WHERE id_date = l_id_date AND id_period = l_id_period;

        FOR row2 IN ( SELECT id, code
                      FROM xxkkbi_dim_region
                      WHERE code NOT IN ('0000', '0077', '5899', '0098', '0099', 'T', '6300') AND id > -1 )
        LOOP
            l_region := row2.code;
            l_id_region := row2.id;

            INSERT INTO temp_2_27
                    SELECT cc.segment4,
                            SUM ( DECODE ( cc.segment3, '000000000', NVL ( accounted_cr, 0 ) - NVL ( accounted_dr, 0 ), 0 ) ) sum_in,
                            SUM ( DECODE ( cc.segment3, '019999999', NVL ( accounted_cr, 0 ) - NVL ( accounted_dr, 0 ), 0 ) ) sum_out,
                            SUM ( DECODE ( cc.segment3, '000000000', 0, '019999999', 0, NVL ( accounted_cr, 0 ) - NVL ( accounted_dr, 0 ) ) ) sum_zach,
                            id_specific
                    FROM gl_gl_je_lines l,
                         gl_gl_je_headers h,
                        (SELECT 
                            code_combination_id,
                            specific.id id_specific,
                            segment1,
                            segment2,
                            segment3,
                            segment4,
                            segment7
                        FROM  
                            apps_gl_code_combinations cc,
                            xxkkbi_dim_specific specific
                        WHERE 
                            chart_of_accounts_id = 50408
                        AND   
                            template_id IS NULL
                        AND ( 
                            segment1 = CASE
                            WHEN 
                                SUBSTR ( l_region, 3, 2 ) = '01'
                            THEN 
                                '02'
                            ELSE
                                '03'
                            END )
                        AND 
                            segment2 LIKE CASE WHEN 
                                SUBSTR ( l_region, 3, 2 ) = '01'
                            THEN
                                SUBSTR ( l_region, 1, 2 ) || '%'
                            ELSE
                                l_region
                            END
                        AND ( segment3 IN ('000000000', '019999999') OR segment3 BETWEEN '021999999' AND '023999999' )
                        AND segment4 BETWEEN '100000' AND '8ßßßßß'
                        AND segment5 = '0'
                        AND segment6 = '0000000'
                        AND segment7 = '1'
                        AND segment4 = specific.code
                        AND specific.date_end >= l_date
                        ) cc
                    WHERE h.ledger_id = 2021
                        AND h.actual_flag = 'A'
                        AND h.currency_code = 'KZT'
                        AND h.je_header_id = l.je_header_id
                        AND l.code_combination_id = cc.code_combination_id
                        AND l.ledger_id = h.ledger_id
                        AND l.status = 'P'
                        AND l.period_name = l_period_name
                        AND l.effective_date = l_date
                    GROUP BY 
                        cc.segment4,
                        cc.id_specific;

            FOR row3 IN ( 
                SELECT 
                    segment4,
                    sum_in,
                    sum_out,
                    sum_zach,
                    id_specific
                    FROM temp_2_27 )
            LOOP
                l_segment4 := row3.segment4;
                l_id_specific := row3.id_specific;

                SELECT NVL ( SUM ( sum_spec ), 0 )
                INTO l_year_sum
                FROM (
                    SELECT 
                        cc.segment4,
                        -1 * end_of_date_balance_num sum_spec
                    FROM apps_gl_daily_balances_v db,
                        (SELECT 
                            code_combination_id,
                            segment1,
                            segment2,
                            segment3,
                            segment4,
                            segment7
                        FROM 
                            apps_gl_code_combinations cc,
                            xxkkbi_dim_specific specific2
                        WHERE 
                            chart_of_accounts_id = 50408
                        AND template_id IS NULL
                        AND ( segment1 = CASE
                            WHEN 
                                SUBSTR ( l_region, 3, 2 ) = '01'
                            THEN
                                '02'
                            ELSE
                                '03'
                            END )
                        AND segment2 LIKE CASE
                            WHEN 
                                SUBSTR ( l_region, 3, 2 ) = '01'
                            THEN
                                SUBSTR ( l_region, 1, 2 ) || '%'
                            ELSE
                                l_region
                            END
                        AND segment3 IN ('000000000', '019999999')
                        AND segment4 = l_segment4
                        AND segment5 = '0'
                        AND segment6 = '0000000'
                        AND segment7 = '1'
                        AND segment4 = specific2.code
                        AND specific2.date_end >= l_date
                        ) cc
                    WHERE   
                        db.code_combination_id = cc.code_combination_id
                        AND db.ledger_id = 2021
                        AND db.actual_flag = 'A'
                        AND db.currency_type = 'U'
                        AND db.currency_code = 'KZT'
                        AND db.period_set_name = 'КЗ Календарь'
                        AND db.period_name = l_period_name
                        AND db.accounting_date = l_date
                    UNION ALL 
                        SELECT 
                            cc.segment4,
                            NVL ( accounted_cr, 0 ) - NVL ( accounted_dr, 0 ) sum_spec
                        FROM 
                            gl_gl_je_lines l,
                            gl_gl_je_headers h,
                            (SELECT 
                                code_combination_id,
                                segment1,
                                segment2,
                                segment3,
                                segment4,
                                segment7
                            FROM 
                                apps_gl_code_combinations cc,
                                xxkkbi_dim_specific specific2
                            WHERE 
                                chart_of_accounts_id = 50408
                            AND 
                                template_id IS NULL
                            AND ( segment1 = CASE
                                WHEN 
                                    SUBSTR ( l_region, 3, 2 ) = '01'
                                THEN
                                    '02'
                                ELSE
                                    '03'
                                END )
                            AND segment2 LIKE CASE 
                                WHEN 
                                    SUBSTR ( l_region, 3, 2 ) = '01'
                                THEN
                                    SUBSTR ( l_region, 1, 2 ) || '%'
                                ELSE
                                    l_region
                                END
                            AND segment3 BETWEEN '021999999' AND '023999999'
                            AND segment4 = l_segment4
                            AND segment5 = '0'
                            AND segment6 = '0000000'
                            AND segment7 = '1'
                            AND segment4 = specific2.code
                            AND specific2.date_end >= l_date
                            ) cc
                        WHERE 
                            h.ledger_id = 2021
                            AND h.actual_flag = 'A'
                            AND h.currency_code = 'KZT'
                            AND h.je_header_id = l.je_header_id
                            AND l.code_combination_id = cc.code_combination_id
                            AND l.ledger_id = h.ledger_id
                            AND l.status = 'P'
                            AND l.period_name = l_period_name
                            AND l.effective_date BETWEEN TRUNC ( l_date, 'MM' ) 
                            AND l_date
                        UNION ALL 
                            SELECT 
                                cc.segment4,
                                NVL ( begin_balance_cr, 0 ) - NVL ( begin_balance_dr, 0 ) sum_spec
                            FROM 
                                gl_gl_balances db,
                                (SELECT 
                                    code_combination_id,
                                    segment1,
                                    segment2,
                                    segment3,
                                    segment4,
                                    segment7
                                FROM 
                                    apps_gl_code_combinations cc,
                                    xxkkbi_dim_specific specific2
                                WHERE 
                                    chart_of_accounts_id = 50408
                                AND template_id IS NULL
                                AND ( segment1 = CASE 
                                    WHEN 
                                        SUBSTR ( l_region, 3, 2 ) = '01'
                                    THEN
                                        '02'
                                    ELSE
                                        '03'
                                    END )
                                AND segment2 LIKE CASE 
                                    WHEN 
                                        SUBSTR ( l_region, 3, 2 ) = '01'
                                    THEN
                                        SUBSTR ( l_region, 1, 2 ) || '%'
                                    ELSE
                                        l_region
                                    END
                                AND segment3 BETWEEN '021999999' AND '023999999'
                                AND segment4 = l_segment4
                                AND segment5 = '0'
                                AND segment6 = '0000000'
                                AND segment7 = '1'
                                AND segment4 = specific2.code
                                AND specific2.date_end >= l_date
                                ) cc
                            WHERE 
                                db.code_combination_id = cc.code_combination_id
                                AND db.ledger_id = 2021
                                AND db.actual_flag = 'A'
                                AND db.currency_code = 'KZT'
                                AND db.period_name = l_period_name
                );

                pkg_fct_log.fct_log_2 (
                    p_fct_name  => l_fct,
                    p_oper_name => 'START INSERT',
                    p_rows_date => l_date,
                    p_oper_descr => l_descr
                    || ' l_id_specific='
                    || l_id_specific
                    || ' l_year_sum='
                    || l_year_sum 
                );

                INSERT INTO 
                    xxkkbi.fct_2_27
                SELECT 
                    l_id_date,
                    l_id_period,
                    -1,
                    l_id_specific,
                    l_id_region,
                    row3.sum_in,
                    row3.sum_out,
                    row3.sum_zach,
                    l_year_sum
                FROM DUAL;

                pkg_fct_log.fct_log_2 (
                    p_fct_name  => l_fct,
                    p_oper_name => 'END INSERT',
                    p_rows_count => 1,
                    p_rows_date => l_date,
                    p_oper_descr => l_descr
                    || ' l_id_specific='
                    || l_id_specific
                    || ' l_year_sum='
                    || l_year_sum 
                );
            END LOOP;

            pkg_fct_log.fct_log_2 ( 
                p_fct_name  => l_fct,
                p_oper_name => 'START INSERT',
                p_rows_date => l_date,
                p_oper_descr => l_descr 
            );

            INSERT INTO 
                xxkkbi.fct_2_27
            SELECT 
                l_id_date AS id_date,
                l_id_period,
                -1,
                id_specific,
                l_id_region,
                0,
                0,
                0,
                sum_spec
            FROM 
            (  
                SELECT 
                    t1.id_specific,
                    NVL ( SUM ( t1.sum_spec ), 0 ) sum_spec
                    FROM 
                        (SELECT 
                            id_specific,
                            -1 * end_of_date_balance_num sum_spec
                            FROM 
                                apps_gl_daily_balances_v db,
                                (SELECT 
                                    specific2.id id_specific,
                                    code_combination_id,
                                    segment1,
                                    segment2,
                                    segment3,
                                    segment4,
                                    segment7
                                    FROM 
                                        apps_gl_code_combinations cc,
                                        xxkkbi_dim_specific specific2
                                        WHERE 
                                            chart_of_accounts_id = 50408
                                            AND template_id IS NULL
                                            AND ( segment1 = CASE 
                                                WHEN 
                                                    SUBSTR ( l_region, 3, 2 ) = '01'
                                                THEN
                                                    '02'
                                                ELSE
                                                    '03'
                                                END )
                                            AND segment2 LIKE CASE
                                                WHEN 
                                                    SUBSTR ( l_region, 3, 2 ) = '01'
                                                THEN
                                                    SUBSTR ( l_region, 1, 2 ) || '%'
                                                ELSE
                                                    l_region
                                                END
                                            AND segment3 IN ('000000000', '019999999')
                                            AND segment5 = '0'
                                            AND segment6 = '0000000'
                                            AND segment7 = '1'
                                            AND segment4 = specific2.code
                                            AND specific2.date_end >= l_date
                                ) cc
                            WHERE 
                                db.code_combination_id = cc.code_combination_id
                            AND db.ledger_id = 2021
                            AND db.actual_flag = 'A'
                            AND db.currency_type = 'U'
                            AND db.currency_code = 'KZT'
                            AND db.period_set_name = 'ÊÇ Êàëåíäàðü'
                            AND db.period_name = l_period_name
                            AND db.accounting_date = l_date
                            UNION ALL
                                SELECT 
                                    id_specific,
                                    NVL ( accounted_cr, 0 ) - NVL ( accounted_dr, 0 ) sum_spec
                                FROM 
                                    gl_gl_je_lines l,
                                    gl_gl_je_headers h,
                                    (SELECT 
                                        specific2.id id_specific,
                                        code_combination_id,
                                        segment1,
                                        segment2,
                                        segment3,
                                        segment4,
                                        segment7
                                    FROM 
                                        apps_gl_code_combinations cc,
                                        xxkkbi_dim_specific specific2
                                    WHERE 
                                        chart_of_accounts_id = 50408
                                    AND template_id IS NULL
                                    AND ( segment1 = CASE
                                        WHEN 
                                            SUBSTR ( l_region, 3, 2 ) = '01'
                                        THEN
                                            '02'
                                        ELSE
                                            '03'
                                        END )
                                    AND segment2 LIKE CASE
                                        WHEN 
                                            SUBSTR ( l_region, 3, 2 ) = '01'
                                        THEN
                                            SUBSTR ( l_region, 1, 2 ) || '%'
                                        ELSE
                                            l_region
                                        END
                                    AND segment3 BETWEEN '021999999' AND '023999999'
                                    AND segment5 = '0'
                                    AND segment6 = '0000000'
                                    AND segment7 = '1'
                                    AND segment4 = specific2.code
                                    AND specific2.date_end >= l_date
                                    ) cc
                                WHERE 
                                    h.ledger_id = 2021
                                AND h.actual_flag = 'A'
                                AND h.currency_code = 'KZT'
                                AND h.je_header_id = l.je_header_id
                                AND l.code_combination_id = cc.code_combination_id
                                AND l.ledger_id = h.ledger_id
                                AND l.status = 'P'
                                AND l.period_name = l_period_name
                                AND l.effective_date BETWEEN TRUNC ( l_date, 'MM' )
                                AND l_date
                                UNION ALL 
                                    SELECT 
                                        id_specific,
                                        NVL ( begin_balance_cr, 0 ) - NVL ( begin_balance_dr, 0 ) sum_spec
                                    FROM 
                                        gl_gl_balances db,
                                        (SELECT 
                                            specific2.id id_specific,
                                            code_combination_id,
                                            segment1,
                                            segment2,
                                            segment3,
                                            segment4,
                                            segment7
                                        FROM 
                                            apps_gl_code_combinations cc,
                                            xxkkbi_dim_specific specific2
                                        WHERE 
                                            chart_of_accounts_id = 50408
                                        AND template_id IS NULL
                                        AND ( segment1 = CASE
                                            WHEN 
                                                SUBSTR ( l_region, 3, 2 ) = '01'
                                            THEN
                                                '02'
                                            ELSE
                                                '03'
                                            END )
                                        AND segment2 LIKE CASE
                                            WHEN 
                                                SUBSTR ( l_region, 3, 2 ) = '01'
                                            THEN
                                                SUBSTR ( l_region, 1, 2 ) || '%'
                                            ELSE
                                                l_region
                                            END
                                        AND segment3 BETWEEN '021999999' AND '023999999'
                                        AND segment5 = '0'
                                        AND segment6 = '0000000'
                                        AND segment7 = '1'
                                        AND segment4 = specific2.code
                                        AND specific2.date_end >= l_date
                                        ) cc
                                    WHERE 
                                        db.code_combination_id = cc.code_combination_id
                                        AND db.ledger_id = 2021
                                        AND db.actual_flag = 'A'
                                        AND db.currency_code = 'KZT'
                                        AND db.period_name = l_period_name
                                        AND segment4 NOT IN (SELECT segment4 FROM temp_2_27)
                        ) t1
                    GROUP BY t1.id_specific
            );

            pkg_fct_log.fct_log_2 ( 
                p_fct_name  => l_fct,
                p_oper_name => 'END INSERT',
                p_rows_count => SQL%ROWCOUNT,
                p_rows_date => l_date,
                p_oper_descr => l_descr 
            );
            COMMIT;

        END LOOP;

    END LOOP;

    pkg_fct_log.fct_log_2 ( 
        p_fct_name  => l_fct,
        p_oper_name => 'END PROCEDURE' 
    );
    RETURN;
EXCEPTION
    WHEN 
        OTHERS
    THEN
        BEGIN
            l_err_code := SQLCODE;
            l_err_msg  := SUBSTR ( SQLERRM, 1, 2000 );
            pkg_fct_log.fct_log_2 ( 
                p_fct_name  => l_fct,
                p_oper_name => 'EXCEPTION',
                p_err_code  => l_err_code,
                p_err_msg   => l_err_msg 
            );
        END;
END kzt_2_27_p;
  • 将操作拆分为不同的操作,而不是 在一个程序中保留所有这些内容

  • 逐行
    逐慢
    ,利用
    批量
    处理和 摆脱
    FOR循环

  • 调优是一个手动过程,PL/SQL和SQL是不同的引擎。两个引擎之间的每个上下文切换都有一个开销。如果
    PL/SQL
    code在集合中循环,对集合中的每个项执行相同的DML操作,则可以通过
    bulk binding
    在一次操作中将整个集合绑定到DML语句来减少
    上下文切换

  • 使用
    FORALL
    语法,它允许我们将集合的内容绑定到单个DML语句,允许对集合中的每一行运行
    DML
    ,而无需每次进行上下文切换


  • 如果可能的话,我希望将每个
    INSERT
    作为一个单独的SQL。只有您知道环境规格和限制。

    六天?涉及多少行,日志是否显示活动和时间?你做了些什么来调查它在哪里慢以及为什么慢?你确定不是一直有什么东西挡住了它吗?所有嵌套循环及其插入和其中的子查询可能都可以消除,并用每个表的单个插入来替换,但我怀疑您是否会找到任何人愿意为您重写整个内容。@AlexPoole,当我刷新收集所有数据的表时,一分钟内大约有一行新行。您可以清楚地看到,有许多相同类型的嵌套查询。然后您需要查看单个语句-我猜子查询正在终止每个插入,可能会被连接替换。但你需要摆脱循环,成批地做事情。集中思考,不要从程序(一行一行)的方法开始。开发人员已经开始(ab)像任何事情一样使用
    CASE
    。@LalitKumarB-是的-带有易读性复合体的臭烘烘的条状螺柱-他们应该像真正的男人一样滥用
    解码
    !!!!!