Oracle 优化PL/SQL代码
我知道在没有规范的情况下很难对代码进行优化,但我也没有规范。有人能在下面的代码中进行一些优化吗?因为此代码执行时间超过6天,但我们需要在6或8小时内运行它。有什么建议吗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
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
code在集合中循环,对集合中的每个项执行相同的DML操作,则可以通过bulk binding
在一次操作中将整个集合绑定到DML语句来减少上下文切换
FORALL
语法,它允许我们将集合的内容绑定到单个DML语句,允许对集合中的每一行运行DML
,而无需每次进行上下文切换如果可能的话,我希望将每个
INSERT
作为一个单独的SQL。只有您知道环境规格和限制。六天?涉及多少行,日志是否显示活动和时间?你做了些什么来调查它在哪里慢以及为什么慢?你确定不是一直有什么东西挡住了它吗?所有嵌套循环及其插入和其中的子查询可能都可以消除,并用每个表的单个插入来替换,但我怀疑您是否会找到任何人愿意为您重写整个内容。@AlexPoole,当我刷新收集所有数据的表时,一分钟内大约有一行新行。您可以清楚地看到,有许多相同类型的嵌套查询。然后您需要查看单个语句-我猜子查询正在终止每个插入,可能会被连接替换。但你需要摆脱循环,成批地做事情。集中思考,不要从程序(一行一行)的方法开始。开发人员已经开始(ab)像任何事情一样使用CASE
。@LalitKumarB-是的-带有易读性复合体的臭烘烘的条状螺柱-他们应该像真正的男人一样滥用解码
!!!!!