ORACLE SQL Tuning Advisor
阿新 • • 發佈:2021-01-21
技術標籤:ORACLE
前言:一直以來SQL調優都是DBA比較費力的技術活,而且很多DBA如果沒有從事過開發的工作,那麼調優更是一項頭疼的工作,即使是SQL調優很厲害的高手,在SQL調優的過程中也要不停的分析執行計劃、加HINT、分析統計資訊等等。從ORACLE 10G開始,資料庫採取了很多智慧化的管理工作,其中SQL優化器(SQL Tuning Advisor:STA),大大的提高了DBA進行SQL優化的效率;
準備測試環境(建立兩個表並插入資料)
create table big_tab as select rownum as id,a.* from sys.all_objects a ;
create table small_tab as select rownum as id,a.* from sys.all_tables a ;
insert into big_tab select * from big_tab;
select count(*) from big_tab;
SQL> select count(*) from big_tab;
COUNT(*)
----------
2657440
select count(*) from small_tab;
SQL> select count(*) from small_tab;
COUNT (*)
----------
2584
查詢測試,檢視最初執行計劃
SQL> set timing on
SQL> set autotrace on
SQL> select count(*) from big_tab a,small_tab b where a.object_name=b.table_name;
COUNT(*)
----------
98112
Execution Plan
----------------------------------------------------------
Plan hash value: 2505897097
---------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 34 | 8902 (1)| 00:01:47 |
| 1 | SORT AGGREGATE | | 1 | 34 | | |
|* 2 | HASH JOIN | | 1439K| 46M| 8902 (1)| 00:01:47 |
| 3 | TABLE ACCESS FULL| SMALL_TAB | 2464 | 41888 | 24 (0)| 00:00:01 |
| 4 | TABLE ACCESS FULL| BIG_TAB | 2653K| 43M| 8872 (1)| 00:01:47 |
---------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("A"."OBJECT_NAME"="B"."TABLE_NAME")
Note
-----
- dynamic sampling used for this statement (level=2)
Statistics
----------------------------------------------------------
139 recursive calls
0 db block gets
40009 consistent gets
40767 physical reads
0 redo size
528 bytes sent via SQL*Net to client
523 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
4 sorts (memory)
0 sorts (disk)
1 rows processed
SQL>
建立調優任務CREATE_TUNING_TASK
SQL> set autot off
SQL> set timing off
SQL>DECLARE
my_task_name VARCHAR2(30);
my_sqltext CLOB;
BEGIN
my_sqltext := 'select count(*) from big_tab a,small_tab b where a.object_name=b.table_name';
my_task_name := DBMS_SQLTUNE.CREATE_TUNING_TASK(
sql_text => my_sqltext,
user_name => 'CHAICHENG',
scope => 'COMPREHENSIVE',
time_limit => 180,
task_name => 'tuning_sql_test',
description => 'Task to tune a query on a specified table');
DBMS_SQLTUNE.EXECUTE_TUNING_TASK( task_name => 'tuning_sql_test');
END;
/
執行建立的調優任務
SQL> exec dbms_sqltune.execute_tuning_task('tuning_sql_test');
PL/SQL procedure successfully completed.
檢視調優任務
SQL> SELECT task_name,status FROM USER_ADVISOR_TASKS WHERE task_name='tuning_sql_test';
TASK_NAME STATUS
------------------------------ -----------
tuning_sql_test COMPLETED
獲取調優報告
SELECT DBMS_SQLTUNE.REPORT_TUNING_TASK('tuning_sql_test') from DUAL;
GENERAL INFORMATION SECTION
-------------------------------------------------------------------------------
Tuning Task Name : tuning_sql_test
Tuning Task Owner : CHAICHENG
Workload Type : Single SQL Statement
Execution Count : 2
Current Execution : EXEC_5930
Execution Type : TUNE SQL
Scope : COMPREHENSIVE
Time Limit(seconds): 180
Completion Status : COMPLETED
Started at : 12/11/2020 15:11:16
Completed at : 12/11/2020 15:11:43
-------------------------------------------------------------------------------
Schema Name: CHAICHENG
SQL ID : 30tv0wjwd7ntn
SQL Text : select count(*) from big_tab a,small_tab b where
a.object_name=b.table_name
-------------------------------------------------------------------------------
FINDINGS SECTION (3 findings)
-------------------------------------------------------------------------------
1- Statistics Finding
---------------------
未分析表格 "CHAICHENG"."SMALL_TAB".
Recommendation
--------------
- 考慮收集此表格的最佳化處理程式統計資訊.
execute dbms_stats.gather_table_stats(ownname => 'CHAICHENG', tabname =>
'SMALL_TAB', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE,
method_opt => 'FOR ALL COLUMNS SIZE AUTO');
Rationale
---------
最佳化處理需要表格的最新統計資訊, 才能選取合適的執行計劃.
2- Statistics Finding
---------------------
未分析表格 "CHAICHENG"."BIG_TAB".
Recommendation
--------------
- 考慮收集此表格的最佳化處理程式統計資訊.
execute dbms_stats.gather_table_stats(ownname => 'CHAICHENG', tabname =>
'BIG_TAB', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE,
method_opt => 'FOR ALL COLUMNS SIZE AUTO');
Rationale
---------
最佳化處理需要表格的最新統計資訊, 才能選取合適的執行計劃.
3- Index Finding (see explain plans section below)
--------------------------------------------------
此敘述語句的執行計劃可以藉由建立一個或多個索引來改進.
Recommendation (estimated benefit: 98.8%)
-----------------------------------------
- 考慮執行「存取建議程式」來改進實際綱要設計, 或建立建議的索引.
create index CHAICHENG.IDX$$_17490001 on CHAICHENG.SMALL_TAB("TABLE_NAME");
- 考慮執行「存取建議程式」來改進實際綱要設計, 或建立建議的索引.
create index CHAICHENG.IDX$$_17490002 on CHAICHENG.BIG_TAB("OBJECT_NAME");
Rationale
---------
建立建議的索引可大幅改進此敘述語句的執行計劃. 然而, 最好是使用代表性的 SQL 工作負載 (相對於單一敘述語句) 來執行「存取建議程式」.
這將可獲得廣泛的索引建議(將索引維護成本和其他空間使用納入考量).
-------------------------------------------------------------------------------
EXPLAIN PLANS SECTION
-------------------------------------------------------------------------------
1- Original
-----------
Plan hash value: 2505897097
---------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 34 | 8902 (1)| 00:01:47 |
| 1 | SORT AGGREGATE | | 1 | 34 | | |
|* 2 | HASH JOIN | | 1439K| 46M| 8902 (1)| 00:01:47 |
| 3 | TABLE ACCESS FULL| SMALL_TAB | 2464 | 41888 | 24 (0)| 00:00:01 |
| 4 | TABLE ACCESS FULL| BIG_TAB | 2653K| 43M| 8872 (1)| 00:01:47 |
---------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("A"."OBJECT_NAME"="B"."TABLE_NAME")
2- Using New Indices
--------------------
Plan hash value: 4182513400
-----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 34 | 106 (6)| 00:00:02 |
| 1 | SORT AGGREGATE | | 1 | 34 | | |
|* 2 | HASH JOIN | | 1439K| 46M| 106 (6)| 00:00:02 |
| 3 | INDEX FAST FULL SCAN| IDX$$_17490001 | 2464 | 41888 | 9 (0)| 00:00:01 |
| 4 | INDEX FAST FULL SCAN| IDX$$_17490002 | 2653K| 43M| 91 (0)| 00:00:02 |
-----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("A"."OBJECT_NAME"="B"."TABLE_NAME")
-------------------------------------------------------------------------------
刪除優化任務
通過呼叫dbms_sqltuen.drop_tuning_task可以刪除已經存在的優化任務
SQL>exec dbms_sqltune.drop_tuning_task(‘tuning_sql_test’);
PL/SQL procedure successfully completed.