為什麼有時 Oracle 資料庫不用索引來尋找資料

來源:互聯網
上載者:User

當你運用 SQL 語言,向資料庫發布一條查詢語句時, ORACLE 將伴隨產生一個“執行計畫”,也就是該語句將通過何種資料搜尋方案執行,是通過全表掃描、還是通過索引搜尋等其它方式。搜尋方案的選用與 ORACLE 的最佳化器息息相關。

SQL 陳述式的執行步驟。

1 文法分析 分析語句的文法是否符合規範,衡量語句中各運算式的意義。

2 語義分析 檢查語句中涉及的所有資料庫物件是否存在,且使用者有相應的許可權。

3 視圖轉換 將涉及視圖的查詢語句轉換為相應的對基表查詢語句。

4 運算式轉換 將複雜的 SQL 運算式轉換為較簡單的等效串連運算式。

5 選擇最佳化器 不同的最佳化器一般產生不同的“執行計畫”

6 選擇串連方式 ORACLE 有三種串連方式,對多表串連 ORACLE 可選擇適當的串連方式。

7 選擇串連順序 對多表串連 ORACLE 選擇哪一對錶先串連,選擇這兩表中哪個表做為來源資料表。

8 選擇資料的搜尋路徑 根據以上條件選擇合適的資料搜尋路徑,如是選用全表搜尋還是利用索引或是其他的方式。

9 運行“執行計畫”

ORACLE 的最佳化器

ORACLE 有兩種最佳化器:基於規則的最佳化器( RBO , Rule Based Optimizer ),和基於代價的最佳化器( CBO , Cost Based Optimizer )。

RBO 自 ORACLE 6 版以來被採用,有著一套嚴格的使用規則,只要你按照它去寫 SQL 陳述式,無論資料表中的內容怎樣,也不會影響到你的“執行計畫”,也就是說對資料不“敏感”, ORACLE 公司已經不再發展這種技術了。

CBO 自 ORACLE 7 版被引入, ORACLE 自 7 版以來採用的許多新技術都是基於 CBO 的,如星型串連排列查詢,雜湊串連查詢,和並行查詢等。 CBO 計算各種可能“執行計畫”的“代價”,即 cost ,從中選用 cost 最低的方案,作為實際運行方案。各“執行計畫”的 cost 的計算根據,依賴於資料表中資料的統計分布, ORACLE 資料庫本身對該統計分布並不清楚,須要分析表和相關的索引,才能搜集到 CBO 所需的資料。

一般而言, CBO 所選擇的“執行計畫”都不會比 RBO 的“執行計畫”差,而且相對而言, CBO 對程式員的要求沒有 RBO 那麼苛刻,節省了程式員為了從多個可能的“執行計畫”中選擇一個最優的方案而花費的調試時間,但在某些場合下也會存在問題。

較典型的問題有:有時,表明明建有索引,但查詢過程顯然沒有用到相關的索引,導致查詢過程耗時漫長,佔用資源巨大,問題到底出在哪兒呢?按照以下順序尋找,基本上能發現原因所在。

尋找原因的步驟

首先,我們要確定資料庫運行在何種最佳化模式下,相應的參數是: 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 陳述式是問題的癥結所在。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.