SQL> create table T_PEEKING (a NUMBER, b char(1), c char(2000)); Table created. SQL>SQL> create index T_PEEKING_IDX1 on T_PEEKING(b); Index created.  SQL> begin  2    for i in 1..1000 loop  3      insert into T_PEEKING values (i, 'A', i);  4    end loop;  5  6    insert into T_PEEKING values (1001, 'B', 1001);  7    insert into T_PEEKING values (1002, 'B', 1002);  8    insert into T_PEEKING values (1003, 'C', 1003);  9 10    commit; 11  end; 12  / PL/SQL PRocedure sUCcessfully completed. SQL>SQL> analyze table T_PEEKING compute statistics for table for all indexes 
for all indexed columns; Table analyzed. SQL>我們看下索引掃描的代價是多少:SQL> show parameter OPTIMIZER_INDEX_COST_ADJ NAME                                 TYPE        VALUE------------------------------------ ----------- ------------------------optimizer_index_cost_adj             integer     100 SQL> delete from plan_table; 0 rows deleted. SQL> SQL> eXPlain plan for select /*+index(a T_PEEKING_IDX1)*/ * from 
T_PEEKING a where b = :V; Explained. SQL> select lpad(' ', 2*(level-1))Operation' 'options' '  2         object_name' 'decode(id, 0, 'Cost='position) "Query  3  Plan_Table"  4      from plan_table  5      start with id = 0  6      connect by prior id = parent_id  7  ; QueryPlan_Table-------------------------------------------------------------------------SELECT STATEMENT   Cost=113  TABLE access BY INDEX ROWID T_PEEKING    INDEX RANGE SCAN T_PEEKING_IDX1 SQL>SQL> delete from plan_table; 3 rows deleted. SQL>SQL> explain plan for select /*+full(a)*/ * from T_PEEKING a where b = :V; Explained. SQL>SQL> select lpad(' ', 2*(level-1))operation' 'options' '  2         object_name' 'decode(id, 0, 'Cost='position) "Query  3  Plan_Table"  4      from plan_table  5      start with id = 0  6      connect by prior id = parent_id  7  ; QueryPlan_Table-------------------------------------------------------------------------SELECT STATEMENT   Cost=75  TABLE ACCESS FULL T_PEEKING SQL>  這時,我們可以計算得出讓優(yōu)化器使用索引(無提示強制)的OPTIMIZER_INDEX_COST_ADJ值應(yīng)該SQL> alter system set OPTIMIZER_INDEX_COST_ADJ=67; System altered. SQL>SQL> delete from plan_table; 2 rows deleted. SQL>SQL> explain plan for select * from T_PEEKING a where b = :V; Explained. SQL>SQL> select lpad(' ', 2*(level-1))operation' 'options' '  2         object_name' 'decode(id, 0, 'Cost='position) "Query  3  Plan_Table"  4      from plan_table  5      start with id = 0  6      connect by prior id = parent_id; QueryPlan_Table-------------------------------------------------------------------------SELECT STATEMENT   Cost=75  TABLE ACCESS FULL T_PEEKING SQL>SQL>SQL> alter system set OPTIMIZER_INDEX_COST_ADJ=66; System altered. SQL>SQL> delete from plan_table; 2 rows deleted. SQL>SQL> explain plan for select * from T_PEEKING a where b = :V; Explained. SQL>SQL> select lpad(' ', 2*(level-1))operation' 'options' '  2         object_name' 'decode(id, 0, 'Cost='position) "Query  3  Plan_Table"  4      from plan_table  5      start with id = 0  6      connect by prior id = parent_id; QueryPlan_Table-------------------------------------------------------------------------SELECT STATEMENT   Cost=75  TABLE ACCESS BY INDEX ROWID T_PEEKING    INDEX RANGE SCAN T_PEEKING_IDX1SQL> alter system set OPTIMIZER_INDEX_COST_ADJ=100; System altered. SQL>SQL> delete from plan_table; 2 rows deleted. SQL>SQL> explain plan for select /*+index(a T_PEEKING_IDX1)*/* from
 T_PEEKING a where b = 'A'; Explained. SQL>SQL> select lpad(' ', 2*(level-1))operation' 'options' '  2         object_name' 'decode(id, 0, 'Cost='position) "Query  3  Plan_Table"  4      from plan_table  5      start with id = 0  6      connect by prior id = parent_id; QueryPlan_Table------------------------------------------------------------------------SELECT STATEMENT   Cost=336  TABLE ACCESS BY INDEX ROWID T_PEEKING    INDEX RANGE SCAN T_PEEKING_IDX1SQL> alter system set OPTIMIZER_INDEX_COST_ADJ=100; System altered. SQL>SQL> delete from plan_table; 3 rows deleted. SQL>SQL> explain plan for select /*+index(a T_PEEKING_IDX1)*/* from 
T_PEEKING a where b = 'B'; Explained. SQL>SQL> select lpad(' ', 2*(level-1))operation' 'options' '  2         object_name' 'decode(id, 0, 'Cost='position) "Query  3  Plan_Table"  4      from plan_table  5      start with id = 0  6      connect by prior id = parent_id; QueryPlan_Table-------------------------------------------------------------------------SELECT STATEMENT   Cost=2  TABLE ACCESS BY INDEX ROWID T_PEEKING    INDEX RANGE SCAN T_PEEKING_IDX1SQL> conn sys/sys as sysdbaConnected.SQL>SQL> alter system set OPTIMIZER_INDEX_COST_ADJ=60; System altered. SQL> analyze table T_PEEKING compute statistics for table for all indexes
 for all indexed columns; Table analyzed. SQL>SQL> set autot traceSQL>SQL> alter session set sql_trace = true; Session altered. SQL>SQL> var v char(1)SQL>SQL> exec :v := 'A'; PL/SQL procedure successfully completed. SQL>SQL> select * from T_PEEKING a where b = :V; 1000 rows selected. SQL>SQL> alter session set sql_trace = false; Session altered.tkprof fuyuncat_ora_5352.trc aaa.txt此時OPTIMIZER_INDEX_COST_ADJ是60,根據(jù)上面的結(jié)論,似乎查詢計劃應(yīng)該選擇掃描索引。但是,這里給綁定變量賦了值"A",這時,優(yōu)化器會“窺視”到這個值,并且在計算掃描成本時按照這個值的成本來計算。因此,得出的查詢計劃是全表掃描,而不是掃描索引,靠tkprof分析的結(jié)果:select * from T_PEEKING a where b = :V  call     count       cpu    elapsed       disk      query    current        rows------- ------  -------- ---------- ---------- ---------- ----------  ----------Parse        1      0.00       0.00          0          0          0           0Execute      1      0.00       0.00          0          0          0           0Fetch       68      0.01       0.07          0        406          0        1000------- ------  -------- ---------- ---------- ---------- ----------  ----------total       70      0.01       0.08          0        406          0        1000 Misses in library cache during parse: 1Optimizer mode: CHOOSEParsing user id: SYS Rows     Row Source Operation-------  ---------------------------------------------------   1000  TABLE ACCESS FULL T_PEEKING (cr=406 pr=0 pw=0 time=5052 us) *************************************************************************SQL> conn sys/sys as sysdbaConnected.SQL>SQL>SQL> set autot traceSQL>SQL> alter session set sql_trace = true; Session altered. SQL>SQL> var v char(1)SQL>SQL> exec :v := 'B'; PL/SQL procedure successfully completed. SQL>SQL> select * from T_PEEKING a where b = :V; 1000 rows selected. SQL>SQL> alter session set sql_trace = false; Session altered.select * from T_PEEKING a where b = :V  call     count       cpu    elapsed       disk      query    current        rows------- ------  -------- ---------- ---------- ---------- ----------  ----------Parse        1      0.00       0.00          0          0          0           0Execute      1      0.00       0.00          0          0          0           0Fetch        2      0.00       0.00          0        340          0           2------- ------  -------- ---------- ---------- ---------- ----------  ----------total        4      0.00       0.00          0        340          0           2 Misses in library cache during parse: 0Optimizer mode: CHOOSEParsing user id: SYS Rows     Row Source Operation-------  ---------------------------------------------------      2  TABLE ACCESS FULL T_PEEKING (cr=340 pr=0 pw=0 time=1005 us)新聞熱點
疑難解答
圖片精選