Oracle 10g中的SQL優化亮點:
1、優化器默認為CBO,OPTIMIZER_MODE默認值為ALL_ROWS。不再使用古老的RBO模式,但RULE、CHOOSE並沒有徹底消失,有些時候仍然可以作為我們調試的工具。
2、CPU Costing的計算方式現在默認為CPU+I/O兩者之和.可通過DBMS_XPLAN.DISPLAY_CURSOR觀察更為詳細的執行計劃。
3、增加了幾個有用SQL Hints:
INDEX_SS[[@block] tabs [inds]],INDEX_SS_ASC,INDEX_SS_DESC;SS為SKIP SCAN的縮寫。skip scan以前討論的很多。
NO_USE_N[[@block] tabs],NO_USE_HAHS,NO_USE_MERGE,NO_INDEX_FFS,NO_INDEX_SS,NO_STAR_TRANSFORMATION,NO_QUERY_TRANSFORMATION.
這幾個HINT不用解釋,一看就知道目的是什麼。
USE_NL_WITH_INDEX([@block] tabs [index]):這個提示和Nested Loops有關,通過提示我們可以指定Nested Loops循環中的內部表,也就是開始循環連接其他表的表。CBO是否會執行取決於指定表是否有索引鍵關聯。
QB_NAME(@blockname) 這個提示可以給某個查詢定義一個name,並且可以在其他hints中使用這個name,並且將這個hints作用到這個name對應的查詢中.其實從10G開始,Oracle對一些特定的查詢自動使用queryblockname
4、10G中支持在hint中使用queryblockname
select * from a1 where id in (select /*+ qb_name(sub1) */ id
from a1 where id in (2,10,12));
Execution Plan
----------------------------------------------------------
Plan hash value: 173249654
-----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2 | 34 | 3 (34)| 00:00:01 |
| 1 | TABLE Access BY INDEX ROWID| A1 | 1 | 14 | 1 (0)| 00:00:01 |
| 2 | NESTED LOOPS | | 2 | 34 | 3 (34)| 00:00:01 |
| 3 | SORT UNIQUE | | 2 | 6 | 1 (0)| 00:00:01 |
| 4 | INLIST ITERATOR | | | | | |
|* 5 | INDEX RANGE SCAN | IDX_A1_ID | 2 | 6 | 1 (0)| 00:00:01 |
|* 6 | INDEX RANGE SCAN | IDX_A1_ID | 1 | | 0 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------
---------------
select * from a1 where id in (select /*+ qb_name(sub1) full(@sub1 a1) */ id
from a1 where id in (2,10,12));
Plan hash value: 1882950619
-----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2 | 34 | 17 (6)| 00:00:01 |
| 1 | TABLE Access BY INDEX ROWID| A1 | 1 | 14 | 1 (0)| 00:00:01 |
| 2 | NESTED LOOPS | | 2 | 34 | 17 (6)| 00:00:01 |
| 3 | SORT UNIQUE | | 2 | 6 | 15 (0)| 00:00:01 |
|* 4 | TABLE Access FULL | A1 | 2 | 6 | 15 (0)| 00:00:01 |
|* 5 | INDEX RANGE SCAN | IDX_A1_ID | 1 | | 0 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------
-----------
修改成錯誤的queryblockname
select * from a1 where id in (select /*+ qb_name(sub1) full(@sub2 a1) */ id from a1 where id in (2,10,12));
Execution Plan
----------------------------------------------------------
Plan hash value: 173249654
-----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2 | 34 | 3 (34)| 00:00:01 |
| 1 | TABLE Access BY INDEX ROWID| A1 | 1 | 14 | 1 (0)| 00:00:01 |
| 2 | NESTED LOOPS | | 2 | 34 | 3 (34)| 00:00:01 |
| 3 | SORT UNIQUE | | 2 | 6 | 1 (0)| 00:00:01 |
| 4 | INLIST ITERATOR | | | | | |
|* 5 | INDEX RANGE SCAN | IDX_A1_ID | 2 | 6 | 1 (0)| 00:00:01 |
|* 6 | INDEX RANGE SCAN | IDX_A1_ID | 1 | | 0 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------
如果指定的queryblockname未定義,還是保持以前的執行計劃,證明queryblockname起作用了.
5、新的hints.spread_no_analysis、spread_min_analysis 用於優化analyze查詢.具體以後測試下
6、10GR2的一些變化.
增強了AWR的報告, 提供了專門的ash報告,可以通過新的ashrpt.sql($Oracle_HOME/rdbms/admin下)腳本產生我們需要的ash報告;提供了類似於statspack獲取AWR庫中某個sql(通過腳本)的統計信息和執行信息
·streams_pool_size現在成為ASSM中的一員
·自動調節DB_FILE_MULTIBLOCK_READ_COUNT參數,Oracle會根據數據庫的訪問自動調節該參數
·增加了SQL的優化模式,提供了SQL Tuning Adsivor,SQL Profile等工具.可自動優化sql語句
·兩個比較重要的視圖:v$PROCESS_MEMORY,動態監控每個進程的pga使用,v$sqlstats某種情況下可以替換v$sql視圖