1. 程式人生 > 其它 >ORACLE SQL Tuning Advisor

ORACLE SQL Tuning Advisor

技術標籤: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.

總結:SQL Tuning Advisor為DBA的調優工作減輕了不少負擔,一般情況下我也是通過這種方法進行調優的,這裡有點小小的建議:工具畢竟是固定的,一般只會針對單個語句給出建議,不會在整個資料庫的整體效能上面去思考該調優方法是否可行,這點必須由DBA把握;DBA還是有必要了解為什麼要這麼調優,才能更好的根據實際情況給出具體的調優辦法,不然調優這種高大上的工作將變得廉價。