索引的兩個知識點

5 附表(索引什麼時候不工作)

    首先要聲明兩個知識點:

    (1)RBO&CBO。
    Oracle有兩種執行優化器,一種是RBO(Rule Based Optimizer)基於規則的優化器,這種優化器是基於sql語句寫法選擇執行路徑的;另一種是CBO(Cost Based Optimizer)基於規則的優化器,這種優化器是Oracle根據統計分析信息來選擇執行路徑,如果表和索引沒有進行分析,Oracle將會使用RBO代替CBO;如果表和索引很久未分析,CBO也有可能選擇錯誤執行路徑,不過CBO是Oracle發展的方向,自8i版本來已經逐漸取代RBO.

    (2)AUTOTRACE。
    要看索引是否被使用我們要藉助Oracle的一個叫做AUTOTRACE功能,它顯示了sql語句的執行路徑,我們能看到Oracle內部是怎麼執行sql的,這是一個非常好的輔助工具,在sql調優裏廣泛被運用。我們來看一下怎麼運用AUTOTRACE:
    ① 由於AUTOTRACE自動爲用戶指定了Execution Plan,因此該用戶使用AUTOTRACE前必須已經建立了PLAN_TABLE。如果沒有的話,請運行utlxplan.sql腳本(它在$ORACLE_HOME/rdbms/admin目錄中)。
    ② AUTOTRACE可以通過運行plustrce.sql腳本(它在$ORACLE_HOME/sqlplus/admin目錄中)來設置,用sys用戶登陸然後運行plustrce.sql後會建立一個PLUSTRACE角色,然後給相關用戶授予PLUSTRACE角色,然後這些用戶就可以使用AUTOTRACE功能了。
    ③ AUTOTRACE的默認使用方法是set autotrace on,但是這方法不總是適合各種場合,特別當返回行數很多的時候。Set autotrace traceonly提供了只查看統計信息而不查詢數據的功能。

SQL> set autotrace on SQL> select * from test; A ---------- 1 Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE 1 0 TABLE ACCESS (FULL) OF 'TEST' Statistics ---------------------------------------------------------- 0 recursive calls 0 db block gets 0 consistent gets 0 physical reads 0 redo size 0 bytes sent via SQL*Net to client 0 bytes received via SQL*Net from client 0 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) rows processed SQL> set autotrace traceonly SQL> select * from test.test; Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE 1 0 TABLE ACCESS (FULL) OF 'TEST' Statistics ---------------------------------------------------------- 0 recursive calls 0 db block gets 0 consistent gets 0 physical reads 0 redo size 0 bytes sent via SQL*Net to client 0 bytes received via SQL*Net from client 0 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) rows processed

    Hints是Oracle提供的一個輔助用法,按字面理解就是‘提示’的意思,確實它起得作用也是提示優化器按它所提供的關鍵字來選擇執行路徑,特別適用於sql調整的時候。使用方法如下:

    {DELETE|INSERT|SELECT|UPDATE} /*+ hint [text] [hint[text]]... */

    具體可參考Oracle SQL Reference。有了前面這些知識點,接下來讓我們來看一下什麼時候索引是不起作用的。以下列出幾種情況。

    (1)類型不匹配時。

SQL> create table test.testindex (a varchar(2),b number); 表已創建。 SQL> create index ind_cola on test.testindex(a); 索引已創建。 SQL> insert into test.testindex values('1',1); 已創建 1 行。 SQL> commit; 提交完成。 SQL> analyze table test.testindex compute statistics for all indexes; 表已分析。 SQL> set autotrace on; SQL> select /*+RULE */* FROM test.testindex where a='1';(使用基於rule的優化器,數據類型匹配的情況下) A B -- ---------- 1 1 Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=HINT: RULE 1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TESTINDEX' 2 1 INDEX (RANGE SCAN) OF 'IND_COLA' (NON-UNIQUE)(使用了索引ind_cola) ―――――――――――――――――――――――――――――――――― SQL> select /*+RULE */* FROM test.testindex where a=1;(數據類型不匹配的情況) A B -- ---------- 1 1 Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=HINT: RULE 1 0 TABLE ACCESS (FULL) OF 'TESTINDEX'(優化器選擇了全表掃描)
發佈了34 篇原創文章 · 獲贊 23 · 訪問量 29萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章