分區剪枝
分區剪枝是指對於分區表或分區索引來說,最佳化器可以自動從FROM和WHERE字句雷根據分區鍵提取 出需要掃描的分區,從而避免全表掃描,減少掃描的資料區塊,提高效能。分區剪枝分為靜態和動態, 靜態分區剪枝發生在編譯階段,動態分區剪枝發生在執行階段,下面我們分別來看看這兩種分區剪枝 執行計畫的異同點。
靜態分區剪枝
靜態分區剪枝在解析階段就知道需要掃描多少個分區,因此執行計畫裡的PSTART和PSTOP明確顯示 掃描的起止分區數,例如:
SQL> explain plan for select * from sales where time_id = to_date('01-jan-2001', 'dd-mon-yyyy');Explained.SQL> select * from table(dbms_xplan.display);PLAN_TABLE_OUTPUT----------------------------------------------------------------------------------------------Plan hash value: 3971874201----------------------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |----------------------------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 673 | 19517 | 27 (8)| 00:00:01 | | || 1 | PARTITION RANGE SINGLE| | 673 | 19517 | 27 (8)| 00:00:01 | 17 | 17 ||* 2 | TABLE ACCESS FULL | SALES | 673 | 19517 | 27 (8)| 00:00:01 | 17 | 17 |----------------------------------------------------------------------------------------------Predicate Information (identified by operation id):--------------------------------------------------- 2 - filter("TIME_ID"=TO_DATE('2001-01-01 00:00:00', 'yyyy-mm-dd hh24:mi:ss'))
上例中的PSTART,PSTOP都等於17表示只需要掃描第17個分區。
動態分區剪枝
如果在解析階段無法知道需要掃描多少分區,只有在運行時才能確定,這時Oracle將自動採用動態 分區剪枝技術,例如:
SQL> explain plan for select sum(amount_sold) from sales where time_id in (select time_id from times where fiscal_year = 2000);Explained.SQL> select * from table(dbms_xplan.display);PLAN_TABLE_OUTPUTPLAN_TABLE_OUTPUT----------------------------------------------------------------------------------------------------Plan hash value: 3827742054----------------------------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |----------------------------------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 1 | 25 | 523 (5)| 00:00:07 | | || 1 | SORT AGGREGATE | | 1 | 25 | | | | ||* 2 | HASH JOIN | | 191K| 4676K| 523 (5)| 00:00:07 | | ||* 3 | TABLE ACCESS FULL | TIMES | 304 | 3648 | 18 (0)| 00:00:01 | | || 4 | PARTITION RANGE SUBQUERY| | 918K| 11M| 498 (4)| 00:00:06 |KEY(SQ)|KEY(SQ)|| 5 | TABLE ACCESS FULL | SALES | 918K| 11M| 498 (4)| 00:00:06 |KEY(SQ)|KEY(SQ)|----------------------------------------------------------------------------------------------------Predicate Information (identified by operation id):--------------------------------------------------- 2 - access("TIME_ID"="TIME_ID") 3 - filter("FISCAL_YEAR"=2000)
在上例中,只有等子查詢返回結果之後,才知道需要掃描多少分區,因此在執行計畫裡,PSTART和 PSTOP無法顯示確切的分區數,而是用關鍵字KEY代替,表示動態分區剪枝。