Я написал блок PL/SQL, который работает в Oracle 9i, в то время как он работает с данными из Oracle Database 11g по ссылке DB. Но код завершает forver. Обработанные данные составляют от 1000 до 2000 записей. Я размещаю код здесь:Улучшение производительности PL/SQL
DECLARE
v_last_comment VARCHAR2 (255);
v_check NUMBER := 0;
CURSOR noschedule_progs
IS
SELECT /*+ DRIVING_SITE(fcr) */
fcr.request_id,
DECODE
(fcpt.user_concurrent_program_name,
'Report Set', fcr.description,
'Request Set Stage', fcr.description,
fcpt.user_concurrent_program_name
) user_concurrent_program_name,
fcr.description, fcr.argument_text, fcr.concurrent_program_id,
fcr.parent_request_id, fcr.actual_start_date,
fcr.actual_completion_date,
ROUND ( (fcr.actual_completion_date - fcr.actual_start_date)
* 24
* 60,
4
) runtime,
'No Schedule' program_status, fu.user_name,
frt.responsibility_name, fcr.logfile_name
FROM [email protected]_link fcr,
[email protected]_link fcpt,
[email protected]_link fu,
[email protected]_link frt
WHERE fcr.concurrent_program_id = fcpt.concurrent_program_id
AND fcr.requested_by = fu.user_id
AND fcr.responsibility_id = frt.responsibility_id
AND fcr.responsibility_application_id = frt.application_id
AND fcr.phase_code = 'C'
AND fcr.status_code IN ('C', 'G', 'E', 'X')
AND fcr.actual_completion_date >= SYSDATE - 1/24
AND fcr.request_id NOT IN (
SELECT NVL (parent_request_id, 1)
FROM [email protected]_link)
AND fcr.requested_by = 1508715
AND fcr.request_id NOT IN (SELECT request_id
FROM allen.alert_main
WHERE program_status = 'No Schedule');
PROCEDURE check_schedule (p_request_id IN NUMBER)
IS
v_count NUMBER (2);
v_parent_id NUMBER (15);
v_last_updated_by NUMBER (15);
v_program VARCHAR2 (255);
v_parent_program VARCHAR2 (255);
v_description VARCHAR2 (255);
v_status VARCHAR2 (2);
BEGIN
SELECT NVL (MAX (phase_code), 'X')
INTO v_status
FROM [email protected]_link
WHERE request_id = p_request_id;
IF v_status != 'R'
THEN
SELECT NVL (MAX (description), 'None')
INTO v_description
FROM [email protected]_link
WHERE request_id = p_request_id;
SELECT COUNT (*)
INTO v_count
FROM [email protected]_link
WHERE parent_request_id = p_request_id
AND concurrent_program_id =
(SELECT concurrent_program_id
FROM [email protected]_link
WHERE request_id = p_request_id)
AND NVL (description, 'None') = v_description;
IF v_count = 0
THEN
SELECT NVL (MAX (parent_request_id), 1)
INTO v_parent_id
FROM [email protected]_link
WHERE request_id = p_request_id;
SELECT NVL (MAX (last_updated_by), 0)
INTO v_last_updated_by
FROM [email protected]_link
WHERE request_id = p_request_id;
IF v_parent_id = -1
THEN
IF v_last_updated_by != 4
THEN
INSERT INTO ikndba.rac_aso_alert_main
SELECT /*+ DRIVING_SITE(fcr) */
ikndba.rac_aso_alert_seq.NEXTVAL, fcr.request_id,
DECODE
(fcpt.user_concurrent_program_name,
'Report Set', fcr.description,
'Request Set Stage', fcr.description,
fcpt.user_concurrent_program_name
) user_concurrent_program_name,
fcr.argument_text, fcr.concurrent_program_id,
fcr.parent_request_id, fcr.actual_start_date,
fcr.actual_completion_date,
ROUND ( ( fcr.actual_completion_date
- fcr.actual_start_date
)
* 24
* 60,
4
) runtime,
'No Schedule' program_status, fu.user_name,
frt.responsibility_name, fcr.logfile_name,
SYSDATE, 'Program Not in Schedule', NULL, 'OPEN',
'SYSTEM'
FROM [email protected]_link fcr,
[email protected]_link fcpt,
[email protected]_link fu,
[email protected]_link frt
WHERE fcr.concurrent_program_id =
fcpt.concurrent_program_id
AND fcr.requested_by = fu.user_id
AND fcr.responsibility_id = frt.responsibility_id
AND fcr.responsibility_application_id =
frt.application_id
AND fcr.request_id = p_request_id
AND fcr.request_id NOT IN (
SELECT request_id
FROM allen.alert_main
WHERE program_status = 'No Schedule');
commit
END IF;
ELSE
SELECT NVL (MAX (DECODE (fcpt.user_concurrent_program_name,
'Report Set', fcr.description,
'Request Set Stage', fcr.description,
fcpt.user_concurrent_program_name
)
),
'Purged'
)
INTO v_program
FROM [email protected]_link fcr,
[email protected]_link fcpt
WHERE request_id = p_request_id
AND fcr.concurrent_program_id = fcpt.concurrent_program_id;
SELECT NVL (MAX (DECODE (fcpt.user_concurrent_program_name,
'Report Set', fcr.description,
'Request Set Stage', fcr.description,
fcpt.user_concurrent_program_name
)
),
'Purged'
)
INTO v_parent_program
FROM [email protected]_link fcr,
[email protected]_link fcpt
WHERE request_id = v_parent_id
AND fcr.concurrent_program_id = fcpt.concurrent_program_id;
IF v_parent_program = v_program AND v_program != 'Purged'
THEN
INSERT INTO ikndba.rac_aso_alert_main
SELECT /*+ DRIVING_SITE(fcr) */
ikndba.rac_aso_alert_seq.NEXTVAL, fcr.request_id,
DECODE
(fcpt.user_concurrent_program_name,
'Report Set', fcr.description,
'Request Set Stage', fcr.description,
fcpt.user_concurrent_program_name
) user_concurrent_program_name,
fcr.argument_text, fcr.concurrent_program_id,
fcr.parent_request_id, fcr.actual_start_date,
fcr.actual_completion_date,
ROUND ( ( fcr.actual_completion_date
- fcr.actual_start_date
)
* 24
* 60,
4
) runtime,
'No Schedule' program_status, fu.user_name,
frt.responsibility_name, fcr.logfile_name,
SYSDATE, 'Program Not in Schedule', NULL, 'OPEN',
'SYSTEM'
FROM [email protected]_link fcr,
[email protected]_link fcpt,
[email protected]_link fu,
[email protected]_link frt
WHERE fcr.concurrent_program_id =
fcpt.concurrent_program_id
AND fcr.requested_by = fu.user_id
AND fcr.responsibility_id = frt.responsibility_id
AND fcr.responsibility_application_id =
frt.application_id
AND fcr.request_id = p_request_id
AND fcr.request_id NOT IN (
SELECT request_id
FROM allen.alert_main
WHERE program_status =
'No Schedule');
COMMIT;
ELSE
SELECT NVL (MAX (parent_request_id), 1)
INTO v_parent_id
FROM [email protected]_link
WHERE request_id =v_parent_id;
check_schedule (v_parent_id);
END IF;
END IF;
END IF;
END IF;
END;
BEGIN
FOR noschedule_progs_row IN noschedule_progs
LOOP
check_schedule (noschedule_progs_row.request_id);
END LOOP;
COMMIT;
EXCEPTION
WHEN OTHERS
THEN
ROLLBACK;
DBMS_OUTPUT.put_line (SQLCODE);
END;
/
Есть ли способ повысить эффективность этой программы?
Я не знаю о других, но я редко терпении вопросов со стенами коды.К вашему кредиту, по крайней мере, он отлично отформатирован. –
Можете ли вы сузить, какие части занимают некоторое время? Это межсетевое общение или заявления, запущенные с обоих концов? Это не обязательно поможет в производительности, но вы всегда должны явно квалифицировать свои объединения, не используйте неявный (разделенный запятыми 'предложение' FROM') синтаксис. И, конечно же, использование циклов и условных выражений не поможет повышению производительности ... У меня также плохое представление о том, сколько транзакций вы можете пройти - вам может быть повезло, если вы сделали это в одном –
Используйте PL/SQL Profiler, чтобы найти компоненты, которые стоит оптимизировать. У вашей IDE, вероятно, есть GUI, чтобы сделать это для вас. –