• 固定执行计划3.1 之 dbms_spm


    说明由于生产环境执行的sql变化较快,版本发布比较频繁,造成sql的执行计划不是很稳定,经常会有一些性能很差的sql出现
    对于这些sql,我们可以使用sql_plan_baseline对执行计划进行绑定,从而使执行计划固定下来
     

    注意:前提是sql最好使用绑定变量,就算有的没有绑定变量,确定字段的值不会改变才行,因为是针对sql_id进行的绑定

            如果sql文本改变,绑定也就无意义了  
     
    解决办法: a. 通过  alter system set cursor_sharing=FORCE;   让系统自动绑定变量
                       (在11.2.0.3版本中测试,经绑定后v$SQL_PLAN执行计划变成了新的执行计划,但是通过set autot on 查看执行计划未改变)
                     b.文本方式,可能通过 sqlprofile 的方式,如自动方式就可以用 force_match=>true
     
    方案一:如果查询的SQL有多个执行计划,其中有合适的执行计划,则可以直接绑定
    1、查询每个执行计划消耗的资源情况
    set lines 150 pages 999;
     col p_user for 99999 ;
     col execs for 9999999 ;
     select a.INSTANCE_NUMBER inst_id,to_char(b.END_INTERVAL_TIME,'yyyymmdd hh24:mi:ss') time,plan_hash_value,buffer_gets_delta/executions_delta get_exec, disk_reads_delta/executions_delta read_exec,cpu_time_delta/executions_delta/1000 cpu_exec_ms ,elapsed_time_delta/executions_delta/1000 elaps_exec_ms ,parsing_schema_id p_user,ROWS_PROCESSED_delta/executions_delta rows_exec,EXECUTIONS_DELTA execs
        from dba_hist_sqlstat a, dba_hist_snapshot b
        where a.sql_id='&sql_id'
        and a.snap_id = b.snap_id
        and a.instance_number = b.instance_number
        and b.END_INTERVAL_TIME between sysdate - 3 and sysdate
        and executions_delta>0 order by 2,1;
    ​
    SELECT DISTINCT(PLAN_HASH_VALUE) FROM V$SQL_PLAN t WHERE SQL_ID = '&sql_id';
    

      

    2、固定执行计划为 
    SQL> select sql_handle, plan_name, accepted, fixed,optimizer_cost from dba_sql_plan_baselines ;
    

     

    declare
     l_pls number;
    begin
     l_pls :=  DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE(sql_id=>'&sql_id',plan_hash_value=>&plan_hash,fixed =>'YES',enabled=>'YES');
    end;
    /
    

     

    ​
    SQL> select sql_handle, plan_name, accepted, fixed,optimizer_cost from dba_sql_plan_baselines
    ​
    SQL_HANDLE PLAN_NAME ACC FIX OPTIMIZER_COST
    ------------------------------ ------------------------------ --- --- --------------
    QL_368f6240d3b95ad6 SQL_PLAN_3d3v2839vkqqqa3c44420 YES YES 34
    

      

     

     
    3、删除固定执行计划

    declare 
    xx PLS_INTEGER; 
    BEGIN 
    xx :=dbms_spm.drop_sql_plan_baseline(sql_handle=>'SQL_9ca68721a7101b8e',plan_name=>null); 
    END; 
    /
    

      

     
    方案二:如果没有合适的执行计划,就要通过自己分析,运用一些hint让sql产生比较好的执行计划
                  或者其它类似SQL 有好的执行计划
     
    1、让原来执行效率低的SQL 生成 HANDLE 
    declare
      l_pls number;
    begin
      l_pls := DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE(sql_id    => '&bad_sql_id',
                                                     plan_hash_value => &bad_sql_plan_hash_value,
                                                     enabled         => 'NO');           # 注意这里是NO 
    end;
    /
    

      

     
    2.  查询刚刚生成的 handle 
    select sql_handle, plan_name, origin, enabled, accepted,fixed,creator,optimizer_cost,sql_text 
    from dba_sql_plan_baselines where origin = 'MANUAL-LOAD' and ENABLED='NO' order by created desc ;
    

      

    3.  用新的SQL_ID  和 新的  sql_plan_hash_value ,绑定老的  sql_handle ,以固定旧的SQL的执行计划
     
    declare
      l_pls number;
    begin
      l_pls := DBMS_SPM.load_plans_from_cursor_cache(sql_id          => '5qp9tjw81a5un',  -- new_SQL_ID'
                                                     plan_hash_value => 1175071277, --new_plan_hash_value
                                                     sql_handle      => 'SQL_9ca68721a7101b8e', --OLD_handle
                                                     fixed =>'YES'
                                                     );
    end;
    /
    

      

     
    以上是从内存中获得较优的执行计划 ,当然也可以从AWR  和 sqlset 优化集中获取 :例从SQLSET中获取
    DECLARE
    my_plans PLS_INTEGER;
    BEGIN
    my_plans := DBMS_SPM.LOAD_PLANS_FROM_SQLSET( sqlset_name >'STS_PS',basic_filter=>'sql_id=''bxajng3zk2vn1''');
    END;
    /
    

      

     
     
     
  • 相关阅读:
    自然数e为底数的指数函数的一个小运用
    Windows产品测试集合整理
    随手写的 IniFiles
    Windows C++ TLS 实现连接163邮箱
    Windows创建个人证书(C++实现,使用 as administrator)
    单进程单线程IOCP的实现(含客户端和服务端)
    32/64位下面的基本数据类型的大小
    WMI 获取操作系统名称和版本
    http 基本代理 C++实现(极简)
    获取内存大小、CPU大小、硬盘大小及使用率
  • 原文地址:https://www.cnblogs.com/cqdba/p/11389488.html
Copyright © 2020-2023  润新知