我要为我的项目执行以下查询:
SELECT 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,
DECODE (fcr.phase_code, 'C', 'No Schedule') program_status,
fu.user_name, frt.responsibility_name, fcr.logfile_name
FROM apps.fnd_concurrent_requests@db_link fcr,
apps.fnd_concurrent_programs_tl@db_link fcpt,
apps.fnd_user@db_link fu,
apps.fnd_responsibility_tl@db_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.actual_completion_date >= (SELECT MAX (alert_logged_time)
FROM allen.main_table
WHERE program_status = 'No Schedule')
AND fcr.phase_code = 'C';
但是上面的查询运行时间太长。当我给出相应的时间作为输入时,而不是
SELECT MAX (alert_logged_time)
FROM allen.main_table
WHERE program_status = 'No Schedule'
我很快就得到了输出。为什么会这样?无论如何要纠正这个?
答案 0 :(得分:2)
我怀疑这种差异的原因是原始的慢查询包含远程和本地表,而修改后的查询只有远程表< /强>
当Oracle查询本地和远程表的混合时,它必须决定连接的发生位置。如果要在本地执行连接,因为默认情况下通常首选连接,则远程表中的所有数据都将通过数据库链接传输。传输的数据量可能比查询的实际结果大许多倍。
另一方面,当所有表在查询中都是远程的时,只传输查询结果,而计算则在远程站点进行。
您可以使用/*+ DRIVING_SITE (<table_alias>)*/
提示指示Oracle在指定表的站点执行连接,从而限制来回传输的数据量。
在查询中添加提示/*+ DRIVING_SITE(fcr) */
应该使其作为修改后的查询执行。
答案 1 :(得分:1)
由于您的子查询符合Oracle scalar subquery caching功能的条件,因此我怀疑性能下降的原因可能是任何(或两者)的缺失索引:
allen.main_table.program_status
allen.main_table.alert_logged_time
答案 2 :(得分:1)
你可以尝试使用连接
SELECT 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,
DECODE (fcr.phase_code, 'C', 'No Schedule') program_status,
fu.user_name, frt.responsibility_name, fcr.logfile_name
FROM apps.fnd_concurrent_requests@aadsp_to_acptr fcr,
apps.fnd_concurrent_programs_tl@aadsp_to_acptr fcpt,
apps.fnd_user@aadsp_to_acptr fu,
apps.fnd_responsibility_tl@aadsp_to_acptr frt,
(SELECT MAX (alert_logged_time) as max_time
FROM allen.main_table
WHERE program_status = 'No Schedule') SQ
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.actual_completion_date >= SQ.max_time
AND fcr.phase_code = 'C';