一、set autotrace trace
disql下執行set autotrace trace開啟AUTOTRACE功能,執行SQL語句,並列印實際的執行計劃。
SQL> set autotrace trace
SQL> select a.employee_name, b.department_name from dmtest.t_emp a join dmtest.t_dept b on a.department_id = b.department_id and b.department_id=102;
目前看到的是資料庫顯示的執行計劃
二、v$cachepln中獲取執行計劃
v$cachepln中儲存了SQL緩衝區中的執行計劃資訊,在ini引數USE_PLN_POOL !=0時才統計。根據v$cachepln中的cache_item可以獲取實際執行計劃資訊:
SQL> select cache_item, sqlstr from v$cachepln where sqlstr like 'select a.employee_name, b.department_name from dmtest.t_emp a join dmtest.t_dept b on a.department_id = b.department_id and b.department_id=102%';
SQL> alter session set events 'immediate trace name plndump level 140244262459496, dump_file ''/opt/dm/sqlplntest.log''';
檢視dump的執行計劃資訊:
這個是真實的執行計劃
有些是因為表中索引過多,最佳化器並沒有走最優的執行計劃,蒐集統計資訊和清理執行計劃快取也並不能解決問題,這時候需要繫結執行計劃。有兩種方式可以處理問題
1.透過改SQL select /*+index(TEST,IDX_TEST_ID) */* from test where id>1;
這種需要在應用去改,加hint的方式解決/*+index(表名,索引名) */
2.通hint注入的方式去改
sp_set_para_value(1,'ENABLE_INJECT_HINT',1); ----開啟hint注入
Ø SQL 只能是語法正確的增刪改查語句;
Ø SQL 會經過系統格式化,格式化之後的 SQL 和指定的規則名稱必須全域性唯一;
Ø HINT 一指定,則全域性生效;
Ø系統檢查 SQL 匹配時,必須是整條語句完全匹配,不能是語句中子查詢匹配;
Ø可透過 SYSINJECTHINT 檢視檢視已指定的 SQL 語句和對應的 HINT。
--對指定SQL增加HINT
SF_INJECT_HINT('sql語句', '引數名(引數值)', '規則名', null,TRUE,TRUE);
實際應用:
SQL> SF_INJECT_HINT('select * from test where id>1;','INDEX(TEST,IDX_TEST_ID)','INJECT1','test injecting hint', TRUE,TRUE);指定該語句使用IDX_TEST_ID索引