SQL计划更改原因



其中一个作业调度器每天都在生产环境中运行,根据过去的执行历史,过去只需要20分钟,但现在已经超过2个小时仍未完成。

a( 如何检查SQL计划今天是否发生了更改?

b( 改变计划的原因可能是什么?由于代码更改,我认识一个。还有什么可能导致计划变更?

您可以使用Active Workload Repository(AWR(检查SQL执行计划是否已更改。首先,您需要找到相关查询的SQL_ID。视图GV$SQL包含最新的SQL。如果在此视图中找不到查询,请尝试DBA_HIST_SQLTEXT

select sql_id, sql_text
from gv$sql
where lower(sql_fulltext) like '%some unique string%';

使用SQL_ID,您可以开始调查历史信息。表DBA_HIST_SQLSTAT包含了许多关于SQL的摘要信息。最重要的列是PLAN_HAS_VALUE;如果该值发生更改,则执行计划已发生更改。

select snap_id, sql_id, plan_hash_value, executions_delta, elapsed_time_delta/100000 seconds_delta
,dba_hist_sqlstat.*
from dba_hist_sqlstat
--join to dba_hist_snapshot if you want to find precise times instead of SNAP_IDs.
where sql_id = '&SQL_ID'
order by dba_hist_sqlstat.snap_id;

如果计划已更改,您可以使用以下内容查看两个计划:

select * from table(dbms_xplan.display_awr(sql_id => '&SQL_ID'));

不幸的是,使用Oracle进行查询调优最困难的部分是,有十几种不同的方式来查看执行计划,每种方式提供的数据都略有不同。

此查询只返回上次执行的数字,但它返回实际的数字和时间,这有助于您关注导致问题的特定操作和等待事件。

select dbms_sqltune.report_sql_monitor(sql_id => '&SQL_ID', type => 'text') from dual;

此查询返回一些附加的执行计划信息,特别是Note部分。大多数图形IDE都省略了这一部分,但这对于复杂的故障排除至关重要。如果发生了什么奇怪的事情,Note部分通常会解释原因。

select * from table(dbms_xplan.display_cursor(sql_id => '&SQL_ID'));

执行计划可能发生变化的原因有很多。如果你在这个问题上添加更多的信息,我可能会做出有根据的猜测。

快速检查:

请检查系统和表格的统计信息是否为最新统计信息。请检查是否对表格或索引进行了任何更改?

最新更新