原因定位:Oracle為何不能使用索引(轉)
首先,我們要確定資料庫執行在何種優化模式下,相應的引數是: optimizer_mode .可在 svrmgrl 中執行" show parameter optimizer_mode" 來檢視。 ORACLE V7 以來預設的設定應是 "choose" ,即如果對已分析的表查詢的話選擇 CBO ,否則選擇 RBO .如果該引數設為" rule ",則不論表是否分析過,一概選用 RBO ,除非在語句中用 hint 強制。
其次,檢查被索引的列或組合索引的首列是否出現在 PL/SQL 語句的 WHERE 子句中,這是"執行計劃"能。
第三,看採用了哪種型別的連線方式。 ORACLE 的共有 Sort Merge Join ( SMJ )、 Hash Join ( HJ )和 Nested Loop Join ( NL )。在兩張表連線,且內表的目標列上建有索引時,只有 Nested Loop 才能有效地利用到該索引。 SMJ 即使相關列上建有索引,最多隻能因索引的存在,避免資料排序過程。 HJ 由於須做 HASH 運算,索引的存在對資料查詢速度幾乎沒有影響。
第四,看連線順序是否允許使用相關索引。假設表 emp 的 deptno 列上有索引,表 dept 的列 deptno 上無索引, WHERE 語句有 emp.deptno=dept.deptno 條件。在做NL 連線時, emp 做為外表,先被訪問,由於連線機制原因,外表的資料訪問方式是全表掃描, emp.deptno 上的索引顯然是用不上,最多在其上。
第五,是否用到系統資料字典表或檢視。由於系統資料字典表都未被分析過,可能導致極差的"執行計劃。
第六,是否存在潛在的資料型別轉換。如將字元型資料與數值型資料比較, ORACLE 會自動將字元型用to_number() 函式進行轉換,從而導致第六種現象的發生。
第七,是否為表和相關的索引蒐集足夠的統計資料。對資料經常有增、刪、改的表最好定期對錶和索引進行分析,可用 SQL 語句" analyze table xxxx compute statistics for all indexes;" . ORACLE 掌。
第八,索引列的選擇性不高。 我們假設典型情況,有表emp ,共有一百萬行資料,但其中的emp.deptno列,資料只有 4 種不同的值,如 10 、 20 、 30 、 40 .雖然 emp 資料行有很多, ORACLE 預設認定表中列的值是在所有資料行均勻分佈的,也就是說每種 deptno 值各有 25 萬資料行與之對應。假設 SQL 搜尋條件 DEPTNO=10 ,利用 deptno 列上的索引進行資料搜尋效率,往往不比全表掃描的高, ORACLE 理不是在4 種deptno 值間平均分配,其中有99 萬行對應著值10 , 5000 行對應值 20 , 3000 行對應值 30 , 2000 行對應值 40 .在這種資料分佈圖案中對除值為 10 外的其它 deptno 值搜尋時,毫無疑問,如果索引能被應用,那麼效率會高出很多。我們可以採用對該索引列進行單獨分析,或用 analyze 語句對該列建立直方圖,對該列蒐集足夠的統計資料,使 ORACLE 在搜尋選擇性較高的值能用上索引。
第九,索引列值是否可為空( NULL )。如果索引列值可以是空值,在 SQL 語句中那些需要返回 NULL 值的操作,將不會用到索引,如 COUNT ( * ),而是用全表掃描。這是因為索引中儲存值不能為全空。
第十,看是否有用到並行查詢( PQO )。並行查詢將不會用到索引。如我們想要用到A 表的IND_COL1 " SELECT /*+ INDEX ( A IND_COL1 ) */ * FROM A WHERE COL1 = XXX;"注意,註釋符必須跟在SELECT之後,且註釋中的" + "要緊跟著註釋起始符" /* "或" -- ",否則 hint 就被認為是一般註釋,對 PL/SQL 語句的執行不產生任何影響。
一種是 EXPLAIN TABLE 方式。
使用者必須首先在自己的模式( SCHEMA )下,建立 PLAN_TABLE 表,執行計劃的每一步驟都將記錄在該表中,建表 SQL 指令碼為在 ${ORACLE_HOME}/rdbms/admin/ 下的 utlxplan.sql 開啟 SQL*PLUS ,輸入" SET AUTOTRACE ON ",然後執行待除錯的 SQL 語句。在給出查詢結果後, ORACLE 將顯示相應的"執行計劃",包括優化器型別、執行代價、連線方式、連線順序、資料搜尋路徑以如果我們不能確定需要跟蹤的具體 SQL 語句,比如某個應用使用一段時間後,響應速度忽然變慢。我們這時可以利用 ORACLE 提供的另一個有力工具 TKPROF ,對應用的執行過程全程跟蹤。
我們要先在系統檢視 V$SESSION 中,可根據 USERID 或 MACHINE ,查出相應的 SID 和 SERIAL# .以SYS 或其他有執行 DBMS_SYSTEM 程式包的使用者連線資料庫,執行" EXECUTE DBMS_SYSTEM.SET_SQL_TRACE_IN_SESSION ( SID , SERIAL# , TRUE );".然後執行應用程式,這時在伺服器端,資料庫參" USER_DUMP_DEST "指示的目錄下,會生成 ora__xxxx.trc 檔案,其中 xxxx 為被跟蹤應用的作業系統程式號。應用程式執行完成後,用命令 tkprof 對該檔案進行分析。
命令示例:" tkprof tracefile outputfile explain=userid/password" .在作業系統 ORACLE 使用者下,鍵入" tkprof ",會有詳細的命令幫助。分析後的輸出檔案 outputfile 中,有每一條 PL/SQL 語句的"執行計劃"、 CPU 佔用、物理讀次數、邏輯讀次數、執行時長等重要資訊。根據輸出檔案的資訊,我們可以很快發現應用中哪條 PL/SQL 語句是問題的癥結所在。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23757700/viewspace-732621/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- (轉)Oracle為什麼不使用我的索引?Oracle索引
- 為何不用MySQL? (轉)MySql
- 為何不能在Oracle表名稱中使用特殊字元?RFOracle字元
- Oracle資料庫索引使用及索引失效總結 轉Oracle資料庫索引
- Percona 5.5定位未使用的索引索引
- MySQL為何不建議使用null列MySqlNull
- (轉)Oracle索引原理Oracle索引
- oracle優化器和不走索引的原因Oracle優化索引
- 【轉載】oracle全文索引的建立和使用Oracle索引
- 在Oracle中怎樣才能使用索引(轉)Oracle索引
- Oracle9i中監視索引的使用(轉)Oracle索引
- 索引為什麼能提供查詢效能...索引
- ORACLE 索引使用規Oracle索引
- 關於oracle的索引重建問題及原因分析Oracle索引
- 【索引】oracle查詢使用索引和不使用索引的比較索引Oracle
- oracle 索引使用及索引失效總結Oracle索引
- Oracle索引HINT的使用Oracle索引
- [轉] Oracle RAC知識索引Oracle索引
- Oracle表與索引的分析及索引重建(轉)Oracle索引
- 使用索引繪圖(轉)索引繪圖
- oracle為什麼不走索引Oracle索引
- [轉]Oracle分割槽索引--本地索引和全域性索引比較Oracle索引
- Oracle分割槽索引--本地索引和全域性索引比較(轉)Oracle索引
- oracle 為什麼沒有使用索引的一種情況Oracle索引
- 為資料庫建立索引(轉)資料庫索引
- 為何不選擇lunix AIOAI
- 如何使用效能分析工具定位SQL執行慢的原因?SQL
- Vue 中為何不可以使用Index 作為Dom的key?VueIndex
- ORACLE 組合索引 使用分析Oracle索引
- Oracle索引的使用規則Oracle索引
- ORACLE 監控索引的使用Oracle索引
- MySQL 選錯索引的原因?MySql索引
- 快速定位不合理的索引——MySQL索引調優索引MySql
- Oracle 索引的三個問題(轉)Oracle索引
- 監控Oracle索引是否被使用?Oracle索引
- oracle 巢狀表 索引表 使用Oracle巢狀索引
- 為什麼使用Redis及其產品定位Redis
- 【MOS:1549181.1】為何在查詢中索引未被使用--為什麼索引沒有被使用索引