2022年11月15日 星期二

7. Index 的優先等級

當一個 Table 有建立多個 Index 時, Oracle 優化器會依照下列原則來優先使用 Index :


  • 當優化器為Rule-Based時優先使用where條件最前面的 Index :

例如一段 SQL 如下 :

SQL> select /*+ RULE */ * from employees 

where manager_id = 100 and department_id = 60;


已知 employees 於 manager_id 上有Index EMP_MANAGER_IX ,於department_id 有Index EMP_DEPARTMENT_IX ,以這個查詢來說, EMP_MANAGER_IX 與 EMP_DEPARTMENT_IX 這兩個 Index 都可以使用,當優化器為 Rule-Based 時,優化器會使用 And-Equal 條件來同時引用兩個 Index ,但放置在 where 條件最前面的 Index 會最先被使用,因此這個查詢 EMP_MANAGER_IX 將優先被使用 :


若將 where 條件的順序交換,則 EMP_DEPARTMENT_IX 優先被使用 :

SQL> select /*+ RULE */ * from employees 

where department_id = 60 and manager_id = 100;


  • 當優化器為Cost-Based時使用選擇性最高的 Index :

以同樣的這段 SQL 來說 :

SQL> select * from employees 

where manager_id = 100 and department_id = 60;


分析欄位的 distinct value , manager_id 為 18 、 department_id 為 11 :


manager_id 的 num_distinct 大於 department_id ,所以 manager_id 的選擇性會比較好,所以這句 SQL 會使用 EMP_MANAGER_IX 這個 Index :


  • Unique Index 將優先被使用 :

同樣以 employees 為例,查詢中使用了 employee_id 與 department_id 條件 :

SQL> select * from employees

        where department_id = 60 and  employee_id = 101;


已知 employee_id 建立為 primary key (EMP_EMP_ID_PK) ,而EMP_DEPARTMENT_IX 為 Non-unique Index,則優化器會選擇 Primary Key 使用 :


這個道理也不難理解,由於 PK 、 Unique Index 為選擇性最佳的 Index ,所以必然優先被使用。


  • 若欄位被重複定義建立在不同的 Index ,則複合索引優先被使用 :

例如欄位 LAST_NAME 被重複建立於單一索引 EMP_LNAME_IX 與複合索引EMP_NAME_IX 上 :


當使用了 LAST_NAME 作為條件,則複合索引優先被使用 :

SQL> select * from employees where last_name='David'


一般來說,複合索引的選擇性通常是優於單一欄位索引,因此複合索引在多數時候會優先被使用。


在了解 Index 的優先等級後,那麼我們在檢視執行計畫時,就可以先簡單的判斷執行計畫的合理性,這些需要優先被使用的 Index 是不是都有被使用到,如果某個 Index 該被使用而實際上優化器沒有選擇它,那接下來我們就要來探討是不是有些情況造成優化器無法選擇而造成 Index 失效的情況。

沒有留言:

張貼留言