【问题标题】:SQL Plan change reasonsSQL 计划更改原因
【发布时间】:2020-08-04 18:28:53
【问题描述】:

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

a) 如何查看今天的 SQL 计划是否发生了变化?

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

【问题讨论】:

  • 您有 AWR/ASH 许可还是使用 statspack?这些也是谷歌搜索的正确关键字。

标签: oracle database-performance database-administration sqlperformance sql-tuning


【解决方案1】:

您可以使用 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_HASH_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'));

许多原因导致执行计划发生变化。如果您在问题中添加其他信息,我可能会做出有根据的猜测。

【讨论】:

    【解决方案2】:

    快速检查:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多