如何在 Oracle 中找到查询使用的执行计划哈希值?

问题描述

如何在 Oracle 中找到查询使用的执行计划哈希值。我有一个查询的行为非常奇怪,因为有时它在 5 秒内运行,有时需要 2 个多小时。

我已经与 DBA 核对过,他告诉我们有多个执行计划可用于此查询,其中 2 个是坏的,只有 1 个是好的。因此,查询执行所需的时间取决于它选择的计划。

是否有一个查询可用于检查使用了哪个执行计划及其哈希值,以便可以将相同的计划固定在查询上。

解决方法

在运行查询后立即调用 dbms_xplan.display_cursor 将为您提供其计划:

create table t (
  c1 int,c2 int
);

insert into t 
with rws as (
  select level x from dual
  connect by level <= 10
)
  select x,x from rws;

set serveroutput off

select * from t where c1 = 1;

select * 
from   table(dbms_xplan.display_cursor(format => 'BASIC LAST'));

PLAN_TABLE_OUTPUT                    
EXPLAINED SQL STATEMENT:              
------------------------              
select * from t where c1 = 1          
                                      
Plan hash value: 1601196873           
                                      
----------------------------------    
| Id  | Operation         | Name |    
----------------------------------    
|   0 | SELECT STATEMENT  |      |    
|   1 |  TABLE ACCESS FULL| T    |    
----------------------------------

create index i on t ( c1 );

select * from t where c1 = 1;

select * 
from   table(dbms_xplan.display_cursor(format => 'BASIC LAST'));

PLAN_TABLE_OUTPUT                                      
EXPLAINED SQL STATEMENT:                                
------------------------                                
select * from t where c1 = 1                            
                                                        
Plan hash value: 3241032591                             
                                                        
----------------------------------------------------    
| Id  | Operation                           | Name |    
----------------------------------------------------    
|   0 | SELECT STATEMENT                    |      |    
|   1 |  TABLE ACCESS BY INDEX ROWID BATCHED| T    |    
|   2 |   INDEX RANGE SCAN                  | I    |    
---------------------------------------------------- 

这仅适用于获取在会话中运行的查询计划。获取其他会话中查询的计划哈希比较棘手。如果它仍在执行,您可以通过查看 from v$session:

select sid,serial#,sql_id,sql_hash_value
from   v$session
where  username is not null

运行完成后,您可以通过查看 v$active_session_history 来获取计划;这使用了采样,因此可能不包括您要查找的 SQL。

要控制语句使用哪个计划,请查看 SQL plan management。使用它,您可以create baselines 定义优化器能够用于查询的计划。

,

您可以使用 DBA_HIST_SQL_PLAN 视图检查执行计划和相关详细信息。

您将从此视图中看到 plan_hash_value

更多详情请见here