SQL訪問顧問SAA(SQL Access Advisor)理論部分十:處理建議
處理建議包含以下方面的內容:
.建議選項
.評估模式
.生成建議
.檢視建議
.SQL工作量日記
.停止建議處理
.標記建議
.修改建議
.生成SQL指令碼
.何時將不再需要建議
建議選項
在建議生成之前,任務的引數首先必須使用dbms_advisor.set_task_parameter過程來進行定義。如 果沒有定義引數,那麼將會使用預設值。使用dbms_advisor.set_task_parameter過程設定引數的語 法如下:
dbms_advisor.set_task_parameter ( task_name in varchar2, parameter in varchar2, value in [varchar2 | number]);
在下面的例子中,將任務MYTASK的儲存大小修改為100MB。這將指示對於建議將有額外的100MB空間。 如果設定為0,說明沒有額外的空間被分配。如果設定為一個負值,則說明指導必須試圖削減當前空間 利用的大小,其大小是引數所指定。
execute dbms_advisor.set_task_parameter('mytask','storage_change', 100000000);
在下面的例子中,將使用valid_table_list引數來過濾掉所有不包括sh.sales和sh.customers表的查詢。
execute dbms_advisor.set_task_parameter('MYTASK', 'VALID_TABLE_LIST', 'SH.SALES, SH.CUSTOMERS');
評估模式
當執行一個任務時,SQL Access Advisor有兩種操作模式:問題解決與評估。預設情況下,SQL Access Advisor將試圖通過尋找索引結構,物化檢視與物化檢視日誌的改進來解決訪問方法的問題。 當只進行評估操作時,SQL Access Advisor將只會給出提供什麼訪問結構讓工作量使用的見意。例如 ,一個問題可能可以通過建立一個新索引,增加一個新列到物化檢視日誌,等等的方法來解決。而當 進行評估操作時,只會生成比如保留索引,保留物化檢視等建議。當進行評估操作時不會考慮對訪問 方法的調整。它是一種嚴格的方法用來檢視現有訪問方法結構和它們如何被提供給工作量所使用。
生成建議
通過執行dbms_advisor_execute_task過程並指定任務名來生成建議。在這個過程執行完成後,可以 檢查dba_advisor_log表來檢查真實的執行狀態與生成的建議數量與運算元。可以使用任務名來查詢
{dba,user}_advisor_recommendations檢視來檢視建議,查詢{dba,user}_advisor_actions檢視來查 看這些建議的操作。
dbms_advisor.execute_task
dbms_advisor.execute_task過程用來對特定任務執行SQL Access Advisor分析或評估。執行任務是 一個同步操作,所以直到操作完成之前不會將控制返回給使用者。任務在執行時或執行完成後,可以檢 查dba_advisor_log表來檢視真實的執行狀態。
執行dbms_advisor.execute_task過程來生成建議,建議是由一個或多個操作組成,比如建立物化視 圖日誌或物化檢視。語法如下:
dbms_advisor.execute_task (task_name in varchar2);
下面的例子執行任務MYTASK:
execute dbms_advisor.execute_task('MYTASK');
檢視建議
由SQL Access Advisor生成的每個建議可以使用目錄檢視來進行檢視,比如{dba,user} _advisor_recommendations檢視。然而,最簡單的方法是使用dbms_advisor.get_task_script過程或 使用EM中的SQL Access Advisor,它是一個圖形工具來顯示建議並且提供了一個超連結來快速檢視那 個語句將會受益於這個建議。由SQL Access Advisor生成的每個建議被連結到受益於它的SQL語句。
下面顯了由SQL Access Advisor由生成的建議(rec_id),以及它們的排名與總收益。排名是一種測量 標準判斷建議對於查詢的重要性。收益是所有查詢使用建議後它的執行成本(優化器成本)的提高總量。
variable workload_name varchar2(255); variable task_name varchar2(255); execute :task_name := 'MYTASK'; execute :workload_name := 'MYWORKLOAD'; select rec_id, rank, benefit from user_advisor_recommendations where task_name = :task_name; REC_ID RANK BENEFIT ---------- ---------- ---------- 1 2 2754 2 3 1222 3 1 5499 4 4 594
為了識別那個查詢受益於那個建議,可以使用dba_*與user_advisor_sqla_wk_stmts。precost與 postcost是分別對不使用與使用建議的發生改變的訪問結構來評估優化器成本的專案(在explain plan中所示)。為了檢視每個查詢,執行以下語句:
select sql_id, rec_id, precost, postcost, (precost-postcost)*100/precost as percent_benefit from user_advisor_sqla_wk_stmts where task_name = :task_name and workload_name = :workload_name; SQL_ID REC_ID PRECOST POSTCOST PERCENT_BENEFIT ---------- ---------- ---------- ---------- --------------- 121 1 3003 249 91.7082917 122 2 1404 182 87.037037 123 3 5503 4 99.9273124 124 4 730 136 81.369863
每一個建議都是由一個或多個操作組成,這些操作必須都執行才能受益於建議。SQL Access Advisor 提供了以下型別的操作:
.create|drop|retain materialized view .create|alter|retain materialized view log .create|drop|retain index .gather stats
create操作關聯新的訪問結構,retain建議指示現有的訪問結構必須保留,drop建議只有在 workload_scope引數設定為full時才會生成。gather stats操作將生成呼叫dbms_stats過程的語句用 來對新生成的訪問結構收集統計資訊。需要注意的是可能多個建議引用了相同操作,然後在生成的建 議指令碼中,對於每個操作只會看到一次。
在下面的例子中,可以看到對於這組建議有許多不同的操作。
select 'action count', count(distinct action_id) cnt from user_advisor_actions where task_name = :task_name; 'ACTIONCOUNT CNT ------------ ---------- Action Count 20 -- see the actions for each recommendations select rec_id, action_id, substr(command,1,30) as command from user_advisor_actions where task_name = :task_name order by rec_id, action_id; REC_ID ACTION_ID COMMAND ---------- ---------- ------------------------------ 1 5 CREATE MATERIALIZED VIEW LOG 1 6 ALTER MATERIALIZED VIEW LOG 1 7 CREATE MATERIALIZED VIEW LOG 1 8 ALTER MATERIALIZED VIEW LOG 1 9 CREATE MATERIALIZED VIEW LOG 1 10 ALTER MATERIALIZED VIEW LOG 1 11 CREATE MATERIALIZED VIEW 1 12 GATHER TABLE STATISTICS 1 19 CREATE INDEX 1 20 GATHER INDEX STATISTICS 2 5 CREATE MATERIALIZED VIEW LOG 2 6 ALTER MATERIALIZED VIEW LOG 2 9 CREATE MATERIALIZED VIEW LOG ...
每個操作有多個屬性,它是關於訪問結構的屬性。每個訪問結構的名稱與表空間被分別儲存在 dba_advisor_actions檢視中的attr1與attr2列中。每個新訪問結構所佔用的空間大小儲存在 dba_advisor_actions檢視中的num_attr1列中。每個操作的所有其它屬性是不同的。
下面的PL/SQL過程可以用來列印建議的一些屬性.
create or replace procedure show_recm (in_task_name in varchar2) is cursor curs is select distinct action_id, command, attr1, attr2, attr3, attr4 from user_advisor_actions where task_name = in_task_name order by action_id; v_action number; v_command varchar2(32); v_attr1 varchar2(4000); v_attr2 varchar2(4000); v_attr3 varchar2(4000); v_attr4 varchar2(4000); v_attr5 varchar2(4000); begin open curs; dbms_output.put_line('========================================='); dbms_output.put_line('Task_name = ' || in_task_name); loop fetch curs into v_action, v_command, v_attr1, v_attr2, v_attr3, v_attr4 ; exit when curs%notfound; dbms_output.put_line('Action ID: ' || v_action); dbms_output.put_line('Command : ' || v_command); dbms_output.put_line('Attr1 (name) : ' || SUBSTR(v_attr1,1,30)); dbms_output.put_line('Attr2 (tablespace): ' || SUBSTR(v_attr2,1,30)); dbms_output.put_line('Attr3 : ' || SUBSTR(v_attr3,1,30)); dbms_output.put_line('Attr4 : ' || v_attr4); dbms_output.put_line('Attr5 : ' || v_attr5); dbms_output.put_line('----------------------------------------'); end loop; close curs; dbms_output.put_line('=========end recommendations============'); end show_recm; / -- see what the actions are using sample procedure set serveroutput on size 99999 execute show_recm(:task_name); A fragment of a sample output from this procedure is as follows: Task_name = MYTASK Action ID: 1 Command : CREATE MATERIALIZED VIEW LOG Attr1 (name) : "SH"."CUSTOMERS" Attr2 (tablespace): Attr3 : ROWID, SEQUENCE Attr4 : INCLUDING NEW VALUES Attr5 : ---------------------------------------- .. ---------------------------------------- Action ID: 15 Command : CREATE MATERIALIZED VIEW Attr1 (name) : "SH"."SH_MV$$_0004" Attr2 (tablespace): "SH_MVIEWS" Attr3 : REFRESH FAST WITH ROWID Attr4 : ENABLE QUERY REWRITE Attr5 : ---------------------------------------- .. ---------------------------------------- Action ID: 19 Command : CREATE INDEX Attr1 (name) : "SH"."SH_IDX$$_0013" Attr2 (tablespace): "SH_INDEXES" Attr3 : "SH"."SH_MV$$_0002" Attr4 : BITMAP Attr5 :
SQL工作量日記
在執行分析處理(execute_task)時,SQL Access Advisor儲存了關於分析日記的有用資訊。可以使用
user_advisor_journal檢視來檢視日記。輸出的資訊量依賴於任務引數journaling的設定。
在匯入工作量時,各種資訊被匯入到SQL工作量日記中。它們可以使用user_advisor_sqlw_journal視 圖來進行檢視。例如,如果一個特定的SQL語句引用了無效的表,表丟失統計資訊或有許可權錯誤,這 些資訊會被記錄在日記中。輸出的資訊量可以通過journaling。
為了關閉日記,執行以下語句:
execute dbms_advisor.set_task_parameter('MYTASK', 'JOURNALING', 0);
為了檢視資訊,執行以下語句:
execute dbms_advisor.set_task_parameter('MYTASK', 'JOURNALING', 4);
為了檢視致命資訊,執行以下語句:
execute dbms_advisor.set_sqlwkld_parameter('MYWORKLOAD', 'JOURNALING', 1);
停止建議處理
如果SQL Access Advisor執行dbms_advisor.execute_task過程花了太長時間來生成建議,可以執行 dbms_advisor.cancel_task過程並傳入任務名來進行停止處理。如果執行dbms_advisor.cancel_task 過程,將不會生成建議。另外可以執行dbms_advisor.interrupt_task過程來終止建議處理。
dbms_advisor.interrupt_task過程會造成一個Advisor操作被終止就像正常結束一樣。因此使用者可以 看到到終止時間點已經格式化的任何建議。
一個終止的任務不能被重啟。語法如下:
dbms_advisor.interrupt_task(task_name in varchar2);:
終止任務MY_TASK
execute dbms_advisor.interrupt_task ('my_task');
dbms_advisor.cancel_task過程會造成一個當前執行操作被終止。一個Advisor操作可能花費了幾秒 來響應這個呼叫。因為所有Advisor任務過程是同步進行的,為了取消一個操作,必須使用一個單獨 的資料庫會話。
取消命令有效的將任務還原到它啟動取消操作開始的條件狀態。因此,取消的任務或資料物件不需要重啟。
dbms_advisor.cancel_task (task_name in varchar2);
取消任務MYTASK:
execute dbms_advisor.cancel_task('MYTASK');
標記建議
預設情況下,所有SQL Access Advisor建議已經準備好被實現了,然而,使用者可以通過執行 dbms_advisor.mark_recommendation過程來選擇跳過或執行所選擇的建議。 dbms_advisor.mark_recommendation過程允許使用者使用reject或ignore設定來註釋一個建議,當生成 實現過程時它將造成dbms_advisor.get_task_script過程來跳過它。語法如下:
dbms_advisor.mark_recommendation ( task_name in varchar2 id in number, action in varchar2);
下面的例子將ID為2的建議標記為reject。這個建議與任何依賴的建議將不會出現在指令碼中。
execute dbms_advisor.mark_recommendation('MYTASK', 2, 'REJECT');
修改建議
可以使用dbms_advisor.update_rec_attributes過程,SQL Access Advisor名字與指派給新物件的關 系,比如在分析操作時的索引與物化檢視。然而,它不是必須要選擇合適的名字,因此可以手動設定 所有者,名字與新物件的表空間名。對於建議引用的現有資料庫物件,所有者與名字不會改變。語法 如下:
dbms_advisor.update_rec_attributes ( task_name in varchar2 rec_id in number, action_id in number, attribute_name in varchar2, value in varchar2);
其中,attribute_name引數可以有以下引數值:
.owner:指定建議物件的所有者
.name:指定建議物件名字
.tablespace:指定建議物件表空間
下面的用來修改SH_MVIEWS操作ID為1,建議ID為1的tablespace屬性
execute dbms_advisor.update_rec_attributes('MYTASK', 1, 1,'TABLESPACE', 'SH_MVIEWS');