溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Oracle固定SQL的執(zhí)行計(jì)劃(一)---SQL Profile

發(fā)布時(shí)間:2020-08-02 23:51:11 來(lái)源:網(wǎng)絡(luò) 閱讀:1246 作者:hbxztc 欄目:關(guān)系型數(shù)據(jù)庫(kù)

我們都希望對(duì)于所有在Oracle數(shù)據(jù)庫(kù)中執(zhí)行的SQL,CBO都能產(chǎn)生出正確的執(zhí)行計(jì)劃,但實(shí)際情況卻并非如此,由于各種各樣的原因(比如目標(biāo)SQL所涉及的對(duì)象的統(tǒng)計(jì)信息的不準(zhǔn)確,或者CBO內(nèi)部一些成本計(jì)算公式的先天缺陷等),導(dǎo)致有時(shí)CBO產(chǎn)生效率不高、甚至是錯(cuò)誤的執(zhí)行計(jì)劃。特別是CBO對(duì)目標(biāo)SQL所產(chǎn)生的初始執(zhí)行計(jì)劃是正確的,后來(lái)由于某種原因(比如統(tǒng)計(jì)信息的變更等)而導(dǎo)致CBO重新對(duì)其產(chǎn)生了錯(cuò)誤的執(zhí)行計(jì)劃,這種執(zhí)行計(jì)劃的改變往往會(huì)導(dǎo)致目標(biāo)SQL執(zhí)行時(shí)間呈數(shù)量級(jí)的遞增,而且常常會(huì)讓我們很困惑:這個(gè)SQL原先跑得好好的,為什么突然就慢得讓人無(wú)法接受?其實(shí)這種SQL執(zhí)行效率突然衰減往往是因?yàn)槟繕?biāo)SQL執(zhí)行計(jì)劃的改變。

我們當(dāng)然希望這樣的改變永遠(yuǎn)不要發(fā)生,即在Oracle數(shù)據(jù)庫(kù)中跑的所有SQL都能有正確的、穩(wěn)定的執(zhí)行計(jì)劃,但實(shí)際上在Oracle 11g的SPM(SQL Plan Management)出現(xiàn)之前,這一點(diǎn)是很難做到的。那么現(xiàn)在退而求其次,如果已經(jīng)出現(xiàn)了執(zhí)行墳?zāi)沟淖兏碈BO已經(jīng)產(chǎn)生了錯(cuò)誤的執(zhí)行計(jì)劃,我們應(yīng)該怎么糾正呢?

我種情況下,我們通常會(huì)重新收集一下統(tǒng)計(jì)信息或者修改目標(biāo)SQL(比如在目標(biāo)SQL中加入Hint等)以糾正錯(cuò)誤的執(zhí)行計(jì)劃。但有時(shí)候重新收集統(tǒng)計(jì)信息并不能解決問題,更糟糕的是,很多情況下是沒有辦法修改目標(biāo)SQL的SQL文本的(比如第三方開發(fā)的系統(tǒng),修改不了源碼,或者目標(biāo)SQL是前臺(tái)框架動(dòng)態(tài)生成的等等),那么這種情況下我們?cè)撛趺崔k呢?

在Oracle 10g/11g及其以后的版本中,我們可以使用SQL Profile或SPM(SQL Plan Management)來(lái)解決上述執(zhí)行計(jì)劃變更的問題,用它們來(lái)調(diào)整、穩(wěn)定目標(biāo)SQL的執(zhí)行計(jì)劃。

本文介紹使用SQL Profile來(lái)穩(wěn)定執(zhí)行計(jì)劃:

Oracle 10g中的SQL Profile(直譯為“SQL概要”)可以說是Oracle 9i中的Stored Outline(直譯為“存儲(chǔ)概要”)的進(jìn)化。Stored Outline能夠?qū)崿F(xiàn)的功能SQL Profile也完全能夠?qū)崿F(xiàn)。

與Stored Outline相比,SQL Profile具備如下優(yōu)點(diǎn):

  • 更容易生成、更改和控制

  • 在SQL語(yǔ)句的支持上做得更好,也就是說適用范圍更廣。

使用SQL Profile可以很容易實(shí)現(xiàn)如下兩個(gè)目的:

  • 鎖定或者說穩(wěn)定執(zhí)行計(jì)劃

  • 在不能修改目標(biāo)SQL的SQL文本的情況下使目標(biāo)SQL語(yǔ)句按指定的執(zhí)行計(jì)劃運(yùn)行。

SQL Profile有兩種類型:一種是Automatic類型,另一種是Manual類型。下面分別介紹這兩種類型:

1. Automatic類型的SQL Profile

Automatic類型的SQL Profile其實(shí)就是針對(duì)目標(biāo)SQL的一些額外的調(diào)整信息,這些信息存儲(chǔ)在數(shù)據(jù)字典里。當(dāng)有了Automatic類型的SQL Profile后,Oracle在產(chǎn)生執(zhí)行計(jì)劃時(shí)就會(huì)根據(jù)它對(duì)目標(biāo)SQL所涉及的統(tǒng)計(jì)信息等內(nèi)容做相應(yīng)的調(diào)整,因而能夠在一定程度上避免產(chǎn)生錯(cuò)誤的執(zhí)行計(jì)劃。你不用擔(dān)心Automatic類型的SQL Profile的準(zhǔn)確性,因?yàn)镺racle會(huì)使用類型于動(dòng)態(tài)采用技術(shù)那樣的手段來(lái)保證這些額外調(diào)整信息相對(duì)準(zhǔn)確。

Automatic類型的SQL Profile不會(huì)像Stored Outline那樣鎖定目標(biāo)SQL的執(zhí)行計(jì)劃,因?yàn)锳utomatic類型的SQL Profile的本質(zhì)就是針對(duì)目標(biāo)SQL的一些額外的調(diào)整信息,這些額外的調(diào)整信息需要與原目標(biāo)SQL的相關(guān)統(tǒng)計(jì)信息等內(nèi)容一起作用才能得到新的執(zhí)行計(jì)劃,即原始SQL的統(tǒng)計(jì)信息等內(nèi)容一旦發(fā)生變化,即使原有Automatic類型的SQL Profile并沒有改變,該SQL的執(zhí)行也可能會(huì)發(fā)生變化。從這個(gè)意義上講,Automatic類型的SQL Profile并不能完全起到穩(wěn)定目標(biāo)SQL的執(zhí)行計(jì)劃的作用,雖然它確實(shí)可以用來(lái)調(diào)整執(zhí)行計(jì)劃。

看一個(gè)在不更改目標(biāo)SQL的SQL文本的情況下使用Automatic類型的SQL Profile來(lái)調(diào)整執(zhí)行計(jì)劃的實(shí)例:

創(chuàng)建測(cè)試表及相關(guān)操作:

zx@MYDB>create table t1 (n number);

Table created.

zx@MYDB>declare
  2  begin
  3  for i in 1..10000 loop
  4  insert into t1 values(i);
  5  end loop;
  6  commit;
  7  end;
  8  /

PL/SQL procedure successfully completed.

zx@MYDB>select count(*) from t1;

  COUNT(*)
----------
     10000

zx@MYDB>create index idx_t1 on t1(n);

Index created.

zx@MYDB>exec dbms_stats.gather_table_stats(ownname=>USER,tabname=>'T1',method_opt=>'for all columns size 1',cascade=>true);

PL/SQL procedure successfully completed.

zx@MYDB>select /*+no_index(t1 idx_t1) */ * from t1 where n=1;

         N
----------
         1

Oracle固定SQL的執(zhí)行計(jì)劃(一)---SQL Profile

從上述顯示內(nèi)容可以看出,目標(biāo)SQL走的是對(duì)表T1的全表掃描(Table Access Full),這個(gè)執(zhí)行計(jì)劃顯然是錯(cuò)誤,這里正確的執(zhí)行墳?zāi)箲?yīng)該是走索引IDX_T1的索引范圍掃描(Index Range Scan)。下面使用SQL Tuning Advisor對(duì)這條SQL生成Automatic類型的SQL Profile。

a.先創(chuàng)建一個(gè)名為my_sql_tuning_task_2的自動(dòng)調(diào)整任務(wù):

zx@MYDB>declare
  2  my_task_name varchar2(30);
  3  my_sqltext clob;
  4  begin
  5  my_sqltext:='select /*+no_index(t1 idx_t1) */ * from t1 where n=1';
  6  my_task_name:=dbms_sqltune.create_tuning_task(
  7  sql_text=>my_sqltext,
  8  user_name=>USER,
  9  scope=>'COMPREHENSIVE',
 10  time_limit=>60,
 11  task_name=>'my_sql_tuning_task_1',
 12  description=>'Task to tune a query on table t1');
 13  end;
 14  /
 
 PL/SQL procedure successfully completed.
 
zx@MYDB>select task_name,status,execution_start,execution_end from user_advisor_log;

TASK_NAME                      STATUS                            EXECUTION_START     EXECUTION_END
------------------------------ --------------------------------- ------------------- -------------------
my_sql_tuning_task_1           INITIAL

注:創(chuàng)建任務(wù)時(shí)可以使用SQL來(lái)創(chuàng)建,可以適用于SQL文本長(zhǎng)的情況。詳情參考官方文檔。

b.執(zhí)行上述自動(dòng)調(diào)整任務(wù)

zx@MYDB>begin
  2  dbms_sqltune.execute_tuning_task(task_name=>'my_sql_tuning_task_1');
  3  end;
  4  /
  
zx@MYDB>zx@MYDB>select task_name,status,execution_start,execution_end from user_advisor_log;

TASK_NAME                      STATUS                            EXECUTION_START     EXECUTION_END
------------------------------ --------------------------------- ------------------- -------------------
my_sql_tuning_task_1           COMPLETED                         2017-02-28 10:59:43 2017-02-28 10:59:44

PL/SQL procedure successfully completed.

c.查看上述自動(dòng)任務(wù)的調(diào)整結(jié)果

zx@MYDB>set long 9000
zx@MYDB>set longchunksize 1000
zx@MYDB>set linesize 800
zx@MYDB>select dbms_sqltune.report_tuning_task('my_sql_tuning_task_1') from dual;

Oracle固定SQL的執(zhí)行計(jì)劃(一)---SQL Profile

Oracle固定SQL的執(zhí)行計(jì)劃(一)---SQL Profile

從上述調(diào)整結(jié)果可以看到,Oracle現(xiàn)在告訴我們:它已經(jīng)為目標(biāo)SQL找到了更好的執(zhí)行計(jì)劃,并且已經(jīng)創(chuàng)建了針對(duì)該SQL的Automatic類型的SQL Profile。如果我們使用accecp_sql_profile接受了這個(gè)SQL Profile,則目標(biāo)SQL的響應(yīng)時(shí)間將會(huì)有86.24%的提升,邏輯讀將會(huì)有95%的提升,并且接受了該SQL Profile后目標(biāo)SQL的執(zhí)行計(jì)劃將會(huì)由原來(lái)的全表掃描變?yōu)樗饕秶鷴呙琛?/p>

上面Automatic類型的SQL Profile所產(chǎn)生的調(diào)整結(jié)果就是我們想要的,所以現(xiàn)在只需按Oracle的提示接受這個(gè)SQL Profile即可:

zx@MYDB>execute dbms_sqltune.accept_sql_profile(task_name =>'my_sql_tuning_task_1', task_owner => 'ZX', replace => TRUE,force_match=>true);

PL/SQL procedure successfully completed.

接受此SQL Profile后我們來(lái)看一下效果,再次執(zhí)行目標(biāo)SQL:

zx@MYDB>select /*+no_index(t1 idx_t1) */ * from t1 where n=1;

         N
----------
         1

Oracle固定SQL的執(zhí)行計(jì)劃(一)---SQL Profile

注意到Note部分有這樣的內(nèi)容“SQL profile SYS_SQLPROF_015a82b353490000 used for this statement”這說明我們剛才接受的SQL Profile已經(jīng)起了作用,該SQL Profile的名字為SYS_SQLPROF_015a82b353490000。從執(zhí)行計(jì)劃中也可以看到,執(zhí)行計(jì)劃確實(shí)已經(jīng)改變了。

另外,DBMS_SQLTUNE.ACCEPT_SQL_PROFILE的輸入?yún)?shù)force_match的默認(rèn)值為FALSE,表示只有在SQL文本完全匹配的情況下才會(huì)應(yīng)用SQL Profile,這種情況下只要目標(biāo)SQL的SQL文本發(fā)生一點(diǎn)變動(dòng),原有的SQL Profile將會(huì)失去作用,如果設(shè)置為TRUE,即使SQL有變動(dòng)SQL Profile也會(huì)強(qiáng)制生效。

刪除SQL Profile

zx@MYDB>exec dbms_sqltune.drop_sql_profile('SYS_SQLPROF_015a82b353490000');

PL/SQL procedure successfully completed.

2. Manual類型的SQL Profile

Manual類型的SQL Profile本質(zhì)上就是一堆Hint的組合,這一堆Hint的組合實(shí)際上來(lái)源于執(zhí)行計(jì)劃中的Outline Data部分的Hint組合。Manual類型的SQL Profile同樣可以在不更改目標(biāo)SQL的SQL文本的情況下,調(diào)整其執(zhí)行計(jì)劃,而且更為重要的是,Manual類型的SQL Profile可以起到很好穩(wěn)定目標(biāo)SQL的執(zhí)行計(jì)劃的作用,這一點(diǎn)是Automatic類型的SQL Profile所不具備的。

看一個(gè)使用Manual類型的SQL Profile實(shí)例固定執(zhí)行計(jì)劃的實(shí)例,使用上面的t1表,刪除上面的SQL Profile,再次執(zhí)行SQL

zx@MYDB>select /*+no_index(t1 idx_t1) */ * from t1 where n=1;

         N
----------
         1

Oracle固定SQL的執(zhí)行計(jì)劃(一)---SQL Profile

從上述輸出可以看出執(zhí)行計(jì)劃仍然走全表掃描。

現(xiàn)在來(lái)創(chuàng)建Manual類型的SQL Profile。這里使用了MOS上的一個(gè)腳本coe_xfr_sql_profile.sql。這個(gè)腳本用于從Shared Pool、AWR Repository中指定SQL的指定執(zhí)行計(jì)劃的Outline Data部分的Hint組合,來(lái)創(chuàng)建Manual類型的SQL Profile。

使用coe_xfr_sql_profile.sql腳本的步驟為

  1. 針對(duì)目標(biāo)SQL使用coe_xfr_sql_profile.sql產(chǎn)生能生成其Manual類型的SQL Profile的腳本A。

  2. 改寫目標(biāo)SQL的文本,在其中使用合適的Hint,直到加入Hint后的SQL能走出我們想要的執(zhí)行計(jì)劃。然后對(duì)加入合適Hint后的SQL使用腳本coe_xfr_sql_profile.sql,產(chǎn)生能生成其Manual類型的SQL Profile的腳本B。

  3. 用腳本B中的Outline Data部分的Hint組合替換掉腳本A的Outline Data部分的Hint組合。

  4. 執(zhí)行腳本A生成針對(duì)原目標(biāo)SQL的Manual類型的SQL Profile。

現(xiàn)在改寫上面的SQL,強(qiáng)制走索引:

zx@MYDB>select /*+index(t1 idx_t1) */ * from t1 where n=1;

         N
----------
         1

Oracle固定SQL的執(zhí)行計(jì)劃(一)---SQL Profile

從執(zhí)行計(jì)劃中可以看出SQL Id和對(duì)應(yīng)的Plan hash value。

全表掃描的SQL Id:6chcc0pvvhqqm Plan hash value:3617692013

索引掃描的SQL Id:2ufquy7xs5nm5 Plan hash value:1369807930

a. 先使用coe_xfr_sql_profile.sql生成全表掃描SQL對(duì)應(yīng)的腳本

zx@MYDB>@scripts/coe_xfr_sql_profile.sql

Parameter 1:
SQL_ID (required)

Enter value for 1: 6chcc0pvvhqqm


PLAN_HASH_VALUE AVG_ET_SECS
--------------- -----------
     3617692013        .002

Parameter 2:
PLAN_HASH_VALUE (required)

Enter value for 2: 3617692013

Values passed to coe_xfr_sql_profile:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SQL_ID	       : "6chcc0pvvhqqm"
PLAN_HASH_VALUE: "3617692013"

SQL>BEGIN
  2    IF :sql_text IS NULL THEN
  3  	 RAISE_APPLICATION_ERROR(-20100, 'SQL_TEXT for SQL_ID &&sql_id. was not found in memory (gv$sqltext_with_newlines) or AWR (dba_hist_sqltext).');
  4    END IF;
  5  END;
  6  /
SQL>SET TERM OFF;
SQL>BEGIN
  2    IF :other_xml IS NULL THEN
  3  	 RAISE_APPLICATION_ERROR(-20101, 'PLAN for SQL_ID &&sql_id. and PHV &&plan_hash_value. was not found in memory (gv$sql_plan) or AWR (dba_hist_sql_plan).');
  4    END IF;
  5  END;
  6  /
SQL>SET TERM OFF;

Execute coe_xfr_sql_profile_6chcc0pvvhqqm_3617692013.sql
on TARGET system in order to create a custom SQL Profile
with plan 3617692013 linked to adjusted sql_text.


COE_XFR_SQL_PROFILE completed.

從輸出可以看出,生成一個(gè)名為coe_xfr_sql_profile_6chcc0pvvhqqm_3617692013.sql的腳本。

b. 用coe_xfr_sql_profile.sql生成索引掃描SQL對(duì)應(yīng)的腳本

SQL>@scripts/coe_xfr_sql_profile.sql

Parameter 1:
SQL_ID (required)

Enter value for 1: 2ufquy7xs5nm5


PLAN_HASH_VALUE AVG_ET_SECS
--------------- -----------
     1369807930        .001

Parameter 2:
PLAN_HASH_VALUE (required)

Enter value for 2: 1369807930

Values passed to coe_xfr_sql_profile:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SQL_ID	       : "2ufquy7xs5nm5"
PLAN_HASH_VALUE: "1369807930"

SQL>BEGIN
  2    IF :sql_text IS NULL THEN
  3  	 RAISE_APPLICATION_ERROR(-20100, 'SQL_TEXT for SQL_ID &&sql_id. was not found in memory (gv$sqltext_with_newlines) or AWR (dba_hist_sqltext).');
  4    END IF;
  5  END;
  6  /
SQL>SET TERM OFF;
SQL>BEGIN
  2    IF :other_xml IS NULL THEN
  3  	 RAISE_APPLICATION_ERROR(-20101, 'PLAN for SQL_ID &&sql_id. and PHV &&plan_hash_value. was not found in memory (gv$sql_plan) or AWR (dba_hist_sql_plan).');
  4    END IF;
  5  END;
  6  /
SQL>SET TERM OFF;

Execute coe_xfr_sql_profile_2ufquy7xs5nm5_1369807930.sql
on TARGET system in order to create a custom SQL Profile
with plan 1369807930 linked to adjusted sql_text.


COE_XFR_SQL_PROFILE completed.

從輸出可以看出,生成一個(gè)名為coe_xfr_sql_profile_2ufquy7xs5nm5_1369807930.sql的腳本。

c. 把后生成的腳本里的Outline Data部分的Hint組合替換到先生成的腳本里,即下圖紅框部分內(nèi)容

Oracle固定SQL的執(zhí)行計(jì)劃(一)---SQL Profile

d. 執(zhí)行coe_xfr_sql_profile_6chcc0pvvhqqm_3617692013.sql腳本

zx@MYDB>@coe_xfr_sql_profile_6chcc0pvvhqqm_3617692013.sql
zx@MYDB>REM
zx@MYDB>REM $Header: 215187.1 coe_xfr_sql_profile_6chcc0pvvhqqm_3617692013.sql 11.4.4.4 2017/02/28 carlos.sierra $
zx@MYDB>REM
zx@MYDB>REM Copyright (c) 2000-2012, Oracle Corporation. All rights reserved.
zx@MYDB>REM
zx@MYDB>REM AUTHOR
zx@MYDB>REM   carlos.sierra@oracle.com
zx@MYDB>REM
zx@MYDB>REM SCRIPT
zx@MYDB>REM   coe_xfr_sql_profile_6chcc0pvvhqqm_3617692013.sql
zx@MYDB>REM
zx@MYDB>REM DESCRIPTION
zx@MYDB>REM   This script is generated by coe_xfr_sql_profile.sql
zx@MYDB>REM   It contains the SQL*Plus commands to create a custom
zx@MYDB>REM   SQL Profile for SQL_ID 6chcc0pvvhqqm based on plan hash
zx@MYDB>REM   value 3617692013.
zx@MYDB>REM   The custom SQL Profile to be created by this script
zx@MYDB>REM   will affect plans for SQL commands with signature
zx@MYDB>REM   matching the one for SQL Text below.
zx@MYDB>REM   Review SQL Text and adjust accordingly.
zx@MYDB>REM
zx@MYDB>REM PARAMETERS
zx@MYDB>REM   None.
zx@MYDB>REM
zx@MYDB>REM EXAMPLE
zx@MYDB>REM   SQL> START coe_xfr_sql_profile_6chcc0pvvhqqm_3617692013.sql;
zx@MYDB>REM
zx@MYDB>REM NOTES
zx@MYDB>REM   1. Should be run as SYSTEM or SYSDBA.
zx@MYDB>REM   2. User must have CREATE ANY SQL PROFILE privilege.
zx@MYDB>REM   3. SOURCE and TARGET systems can be the same or similar.
zx@MYDB>REM   4. To drop this custom SQL Profile after it has been created:
zx@MYDB>REM      EXEC DBMS_SQLTUNE.DROP_SQL_PROFILE('coe_6chcc0pvvhqqm_3617692013');
zx@MYDB>REM   5. Be aware that using DBMS_SQLTUNE requires a license
zx@MYDB>REM      for the Oracle Tuning Pack.
zx@MYDB>REM   6. If you modified a SQL putting Hints in order to produce a desired
zx@MYDB>REM      Plan, you can remove the artifical Hints from SQL Text pieces below.
zx@MYDB>REM      By doing so you can create a custom SQL Profile for the original
zx@MYDB>REM      SQL but with the Plan captured from the modified SQL (with Hints).
zx@MYDB>REM
zx@MYDB>WHENEVER SQLERROR EXIT SQL.SQLCODE;
zx@MYDB>REM
zx@MYDB>VAR signature NUMBER;
zx@MYDB>VAR signaturef NUMBER;
zx@MYDB>REM
zx@MYDB>DECLARE
  2  sql_txt CLOB;
  3  h       SYS.SQLPROF_ATTR;
  4  PROCEDURE wa (p_line IN VARCHAR2) IS
  5  BEGIN
  6  DBMS_LOB.WRITEAPPEND(sql_txt, LENGTH(p_line), p_line);
  7  END wa;
  8  BEGIN
  9  DBMS_LOB.CREATETEMPORARY(sql_txt, TRUE);
 10  DBMS_LOB.OPEN(sql_txt, DBMS_LOB.LOB_READWRITE);
 11  -- SQL Text pieces below do not have to be of same length.
 12  -- So if you edit SQL Text (i.e. removing temporary Hints),
 13  -- there is no need to edit or re-align unmodified pieces.
 14  wa(q'[select /*+no_index(t1 idx_t1) */ * from t1 where n=1 ]');
 15  DBMS_LOB.CLOSE(sql_txt);
 16  h := SYS.SQLPROF_ATTR(
 17  q'[BEGIN_OUTLINE_DATA]',
 18  q'[IGNORE_OPTIM_EMBEDDED_HINTS]',
 19  q'[OPTIMIZER_FEATURES_ENABLE('11.2.0.1')]',
 20  q'[DB_VERSION('11.2.0.1')]',
 21  q'[ALL_ROWS]',
 22  q'[OUTLINE_LEAF(@"SEL$1")]',
 23  q'[INDEX(@"SEL$1" "T1"@"SEL$1" ("T1"."N"))]',
 24  q'[END_OUTLINE_DATA]');
 25  :signature := DBMS_SQLTUNE.SQLTEXT_TO_SIGNATURE(sql_txt);
 26  :signaturef := DBMS_SQLTUNE.SQLTEXT_TO_SIGNATURE(sql_txt, TRUE);
 27  DBMS_SQLTUNE.IMPORT_SQL_PROFILE (
 28  sql_text    => sql_txt,
 29  profile     => h,
 30  name        => 'coe_6chcc0pvvhqqm_3617692013',
 31  description => 'coe 6chcc0pvvhqqm 3617692013 '||:signature||' '||:signaturef||'',
 32  category    => 'DEFAULT',
 33  validate    => TRUE,
 34  replace     => TRUE,
 35  force_match => FALSE /* TRUE:FORCE (match even when different literals in SQL). FALSE:EXACT (similar to CURSOR_SHARING) */ );
 36  DBMS_LOB.FREETEMPORARY(sql_txt);
 37  END;
 38  /

PL/SQL procedure successfully completed.

zx@MYDB>WHENEVER SQLERROR CONTINUE
zx@MYDB>SET ECHO OFF;

            SIGNATURE
---------------------
  3589138201450662673


           SIGNATUREF
---------------------
  8068435081012723673


... manual custom SQL Profile has been created


COE_XFR_SQL_PROFILE_6chcc0pvvhqqm_3617692013 completed

e. 執(zhí)行完成后再次查看目標(biāo)SQL的執(zhí)行計(jì)劃

zx@MYDB>select /*+no_index(t1 idx_t1) */ * from t1 where n=1;

         N
----------
         1

Oracle固定SQL的執(zhí)行計(jì)劃(一)---SQL Profile

從執(zhí)行計(jì)劃中可以看出已經(jīng)走了INDEX RANGE SCAN,而且note部分提示SQL profile coe_6chcc0pvvhqqm_3617692013 used for this statement,說明執(zhí)行sql時(shí)使用了該SQL Profile。

如果想在目標(biāo)SQL的SQL文本發(fā)生變動(dòng)時(shí)SQL Profile依然生效,則需要修改生成的腳本里的force_match=>true。

參考:《基于Oracle的SQL優(yōu)化》

官方文檔:http://docs.oracle.com/cd/E11882_01/server.112/e41573/sql_tune.htm#PFGRF94854

http://docs.oracle.com/cd/E11882_01/appdev.112/e40758/d_sqltun.htm#CHDGAJCI

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI