看懂Oracle執行計畫是最佳化的第一步,讓我們從下面的例子開始吧。
下面為補充內容
1、建立測試表
[sql] view plain copy SQL> create table t as select 1 id,object_name from dba_objects; Table created SQL> update t set id=99 where rownum=1; 1 row updated SQL> commit; Commit complete SQL> create index t_ind on t(id); Index created
oracle最佳化器:RBO和CBO兩種, 從oracle10g開始最佳化器已經拋棄了RBO,下面的列子說明CBO大概是怎樣的
[sql] view plain copy SQL> select /*+dynamic_sampling(t 0) */* from t where id=1; 50819 rows selected. Execution Plan ---------------------------------------------------------- Plan hash value: 1376202287 ------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 195 | 15405 | 51 (0)| 00:00:01 | | 1 | TABLE ACCESS BY INDEX ROWID| T | 195 | 15405 | 51 (0)| 00:00:01 | |* 2 | INDEX RANGE SCAN | T_IND | 78 | | 50 (0)| 00:00:01 | ------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("ID"=1)
現象t表還沒有被分析,提示/*+dynamic_sampling(t 0) */*的目的是讓CBO無法通過動態採樣擷取表中的實際資料情況,此時CBO只能根據T表中非常有限的資訊(比如表中的extents數量,資料區塊的數量)來猜測表中的資料。從結果中可以看到CBO猜出表中id=1的有195條,這個數值對於表的總數來說,是一個非常小的值,所以CBO選擇了索引而不是全表掃描。
而實際情況如下所示:
[sql] view plain copy SQL> select * from t where