• 不修改sql文本情況下,改變其執行計劃


    不修改sql文本情況下,改變其執行計劃

    可以使用sql profile和spm(sql plan manage),本文主要介紹SPM方式

    sql profile參考sql profile固定執行計劃

    步驟

    1.手動生成SQL Plan Baseline

    DECLARE
       V_TEMP   NUMBER;
    BEGIN
       V_TEMP :=
          DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE (SQL_ID            => '原目标的sql_id',
                                                 PLAN_HASH_VALUE   => 原目标sql的执行计划HASH值);
    END;
    

    2.改寫原SQL,加入hint,生成正確的執行計劃

    -- SQL_ID和PLAN HASH VALUE可以在v$sql查找
    -- SQL_HANDLE可以在DBA_DBA_SQL_PLAN_BASELINES中查找
    DECLARE
       V_TEMP   NUMBER;
    BEGIN
       V_TEMP :=
          DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE (
             SQL_ID            => '改写SQL的SQL_ID',
             PLAN_HASH_VALUE   => 改写SQL执行计划HASH值,
             SQL_HANDLE        => '第一步生成的HANDLE');
    END;
    

    3.刪除第一步生成的SQL Plan Baseline

    DECLARE
       V_TEMP   NUMBER;
    BEGIN
       V_TEMP :=
          DBMS_SPM.DROP_SQL_PLAN_BASELINE (
             SQL_HANDLE   => '原目标HANDLE',
             PLAN_NAME    => '原目标PLAN_NAME');
    END;
    

    實驗

    1.創建測試環境

    CREATE TABLE TEST_SPM AS SELECT * FROM DBA_OBJECTS;
    
    CREATE INDEX IX_TEST_SPM_OBJECT_ID ON TEST_SPM(OBJECT_ID);
    

    2.構造原SQL並查看執行計劃

    SELECT /*+NO_INDEX(TEST_SPM IX_TEST_SPM_OBJECT_ID)*/* FROM TEST_SPM WHERE OBJECT_ID=10;
    SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR());
    

    3.生成原SQL的SQL Plan Baseline

    -- 生成
    DECLARE
       V_TEMP   NUMBER;
    BEGIN
       V_TEMP :=
          DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE (SQL_ID            => 'cjdf02m61dsd9',
                                                 PLAN_HASH_VALUE   => 1145642998);
    END;
    -- 查看,因為數據庫的cursor_sharing為force,所以值被替代為變量
    SELECT SQL_HANDLE,PLAN_NAME,SUBSTR(SQL_TEXT,0,100) SQL_TEXT FROM DBA_SQL_PLAN_BASELINES 
    

    4.修改sql並查看執行計劃

    SELECT /*+INDEX(TEST_SPM IX_TEST_SPM_OBJECT_ID)*/* FROM TEST_SPM WHERE OBJECT_ID=10;
    SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR());
    

    5.用修改後的SQL的SQL_ID,PLAN HASH VALUE和原SQL的SQL HANDLE生成新的SQL PLAN BASELINE

    -- 生成
    DECLARE
       V_TEMP   NUMBER;
    BEGIN
       V_TEMP :=
          DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE (
             SQL_ID            => 'cju4dakqwvft7',
             PLAN_HASH_VALUE   => 3777949824,
             SQL_HANDLE        => 'SQL_9fa71106593b209e');
    END;
    -- 查看
    SELECT SQL_HANDLE,PLAN_NAME,TO_CHAR(SUBSTR(SQL_TEXT,0,100)) SQL_TEXT FROM DBA_SQL_PLAN_BASELINES;
    

    6.刪除原SQL的SQL PLAN BASELINE

    DECLARE
       V_TEMP   NUMBER;
    BEGIN
       V_TEMP :=
          DBMS_SPM.DROP_SQL_PLAN_BASELINE (
             SQL_HANDLE   => 'SQL_9fa71106593b209e',
             PLAN_NAME    => 'SQL_PLAN_9z9sj0tcmq84yeb1890ae');
    END;
    

    7.查看原SQL的執行計劃

    SELECT /*+NO_INDEX(TEST_SPM IX_TEST_SPM_OBJECT_ID)*/* FROM TEST_SPM WHERE OBJECT_ID=10;
    SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR());
    

  • 相关阅读:
    mvc中HttpPost理解
    javascrip格式
    asp.net ToString()格式汇总
    Datatable根据多行排序
    sql server 判断是否存在数据库,表,列,视图
    IsPostBack是什么意思,如何运用?
    JS apply()的使用详解
    C++设计模式-Command命令模式
    C++ 继承和包含的区别?
    命令模式
  • 原文地址:https://www.cnblogs.com/monkey6/p/15247080.html
Copyright © 2020-2023  润新知