国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數據庫 > Oracle > 正文

ORACLE SQL性能優化 (下)(1)

2024-08-29 13:43:05
字體:
來源:轉載
供稿:網友
26. 索引的操作

Oracle對索引有兩種訪問模式.

索引唯一掃描 ( INDEX UNIQUE SCAN)

大多數情況下, 優化器通過WHERE子句訪問INDEX.

例如: 表LODGING有兩個索引 : 建立在LODGING列上的唯一性索引LODGING_PK和建立在MANAGER列上的非唯一性索引LODGING$MANAGER.

SELECT *

FROM LODGING

WHERE LODGING = ‘ROSE HILL';

在內部 , 上述SQL將被分成兩步執行, 首先 , LODGING_PK 索引將通過索引唯一掃描的方式被訪問 , 獲得相對應的ROWID, 通過ROWID訪問表的方式 執行下一步檢索.

假如被檢索返回的列包括在INDEX列中,ORACLE將不執行第二步的處理(通過ROWID訪問表). 因為檢索數據保存在索引中, 單單訪問索引就可以完全滿足查詢結果.

下面SQL只需要INDEX UNIQUE SCAN 操作.

SELECT LODGING

FROM LODGING

WHERE LODGING = ‘ROSE HILL';

索引范圍查詢(INDEX RANGE SCAN)

適用于兩種情況:

1. 基于一個范圍的檢索

2. 基于非唯一性索引的檢索

例1:

SELECT LODGING

FROM LODGING

WHERE LODGING LIKE ‘M%';

WHERE子句條件包括一系列值, ORACLE將通過索引范圍查詢的方式查詢LODGING_PK . 由于索引范圍查詢將返回一組值, 它的效率就要比索引唯一掃描低一些.

例2:

SELECT LODGING

FROM LODGING

WHERE MANAGER = ‘BILL GATES';

這個SQL的執行分兩步, LODGING$MANAGER的索引范圍查詢(得到所有符合條件記錄的ROWID) 和下一步同過ROWID訪問表得到LODGING列的值. 由于LODGING$MANAGER是一個非唯一性的索引,數據庫不能對它執行索引唯一掃描.

由于SQL返回LODGING列,而它并不存在于LODGING$MANAGER索引中, 所以在索引范圍查詢后會執行一個通過ROWID訪問表的操作.

WHERE子句中, 假如索引列所對應的值的第一個字符由通配符(WILDCARD)開始, 索引將不被采用.

SELECT LODGING

FROM LODGING

WHERE MANAGER LIKE ‘%HANMAN';

在這種情況下,ORACLE將使用全表掃描. 27. 基礎表的選擇

基礎表(Driving Table)是指被最先訪問的表(通常以全表掃描的方式被訪問). 根據優化器的不同, SQL語句中基礎表的選擇是不一樣的.

假如你使用的是CBO (COST BASED OPTIMIZER),優化器會檢查SQL語句中的每個表的物理大小,索引的狀態,然后選用花費最低的執行路徑.

假如你用RBO (RULE BASED OPTIMIZER) , 并且所有的連接條件都有索引對應, 在這種情況下, 基礎表就是FROM 子句中列在最后的那個表.

舉例:

SELECT A.NAME , B.MANAGER

FROM WORKER A,

LODGING B

WHERE A.LODGING = B.LODING;

由于LODGING表的LODING列上有一個索引, 而且WORKER表中沒有相比較的索引, WORKER表將被作為查詢中的基礎表.

28. 多個平等的索引

當SQL語句的執行路徑可以使用分布在多個表上的多個索引時, ORACLE會同時使用多個索引并在運行時對它們的記錄進行合并, 檢索出僅對全部索引有效的記錄.

在ORACLE選擇執行路徑時,唯一性索引的等級高于非唯一性索引. 然而這個規則只有當WHERE子句中索引列和常量比較才有效.假如索引列和其他表的索引類相比較. 這種子句在優化器中的等級是非常低的.

假如不同表中兩個想同等級的索引將被引用, FROM子句中表的順序將決定哪個會被率先使用. FROM子句中最后的表的索引將有最高的優先級.

假如相同表中兩個想同等級的索引將被引用, WHERE子句中最先被引用的索引將有最高的優先級.

舉例:

DEPTNO上有一個非唯一性索引,EMP_CAT也有一個非唯一性索引.

SELECT ENAME,

FROM EMP

WHERE DEPT_NO = 20

AND EMP_CAT = ‘A';

這里,DEPTNO索引將被最先檢索,然后同EMP_CAT索引檢索出的記錄進行合并. 執行路徑如下:

TABLE access BY ROWID ON EMP

AND-EQUAL

INDEX RANGE SCAN ON DEPT_IDX

INDEX RANGE SCAN ON CAT_IDX

29. 等式比較和范圍比較

當WHERE子句中有索引列, ORACLE不能合并它們,ORACLE將用范圍比較.

舉例:

DEPTNO上有一個非唯一性索引,EMP_CAT也有一個非唯一性索引.

SELECT ENAME

FROM EMP

WHERE DEPTNO > 20

AND EMP_CAT = ‘A';

這里只有EMP_CAT索引被用到,然后所有的記錄將逐條與DEPTNO條件進行比較. 執行路徑如下:

TABLE ACCESS BY ROWID ON EMP

INDEX RANGE SCAN ON CAT_IDX

30. 不明確的索引等級



當ORACLE無法判定索引的等級高低差別,優化器將只使用一個索引,它就是在WHERE子句中被列在最前面的.

舉例:

DEPTNO上有一個非唯一性索引,EMP_CAT也有一個非唯一性索引.

SELECT ENAME

FROM EMP

WHERE DEPTNO > 20

AND EMP_CAT > ‘A';

這里, ORACLE只用到了DEPT_NO索引. 執行路徑如下:

TABLE ACCESS BY ROWID ON EMP

INDEX RANGE SCAN ON DEPT_IDX

譯者按: 我們來試一下以下這種情況:

SQL> select index_name, uniqueness from user_indexes where table_name = 'EMP';

INDEX_NAME UNIQUENES

------------------------------ ---------

EMPNO UNIQUE

EMPTYPE NONUNIQUE

SQL> select * from emp where empno >= 2 and emp_type = 'A' ;

no rows selected

Execution Plan

----------------------------------------------------------

0 SELECT STATEMENT Optimizer=CHOOSE

1 0 TABLE ACCESS (BY INDEX ROWID) OF 'EMP'

2 1 INDEX (RANGE SCAN) OF 'EMPTYPE' (NON-UNIQUE)

雖然EMPNO是唯一性索引,但是由于它所做的是范圍比較, 等級要比非唯一性索引的等式比較低!
26. 索引的操作

ORACLE對索引有兩種訪問模式.

索引唯一掃描 ( INDEX UNIQUE SCAN)

大多數情況下, 優化器通過WHERE子句訪問INDEX.

例如: 表LODGING有兩個索引 : 建立在LODGING列上的唯一性索引LODGING_PK和建立在MANAGER列上的非唯一性索引LODGING$MANAGER.

SELECT *

FROM LODGING

WHERE LODGING = ‘ROSE HILL';

在內部 , 上述SQL將被分成兩步執行, 首先 , LODGING_PK 索引將通過索引唯一掃描的方式被訪問 , 獲得相對應的ROWID, 通過ROWID訪問表的方式 執行下一步檢索.

假如被檢索返回的列包括在INDEX列中,ORACLE將不執行第二步的處理(通過ROWID訪問表). 因為檢索數據保存在索引中, 單單訪問索引就可以完全滿足查詢結果.

下面SQL只需要INDEX UNIQUE SCAN 操作.

SELECT LODGING

FROM LODGING

WHERE LODGING = ‘ROSE HILL';

索引范圍查詢(INDEX RANGE SCAN)

適用于兩種情況:

1. 基于一個范圍的檢索

2. 基于非唯一性索引的檢索

例1:

SELECT LODGING

FROM LODGING

WHERE LODGING LIKE ‘M%';

WHERE子句條件包括一系列值, ORACLE將通過索引范圍查詢的方式查詢LODGING_PK . 由于索引范圍查詢將返回一組值, 它的效率就要比索引唯一掃描低一些.

例2:

SELECT LODGING

FROM LODGING

WHERE MANAGER = ‘BILL GATES';

這個SQL的執行分兩步, LODGING$MANAGER的索引范圍查詢(得到所有符合條件記錄的ROWID) 和下一步同過ROWID訪問表得到LODGING列的值. 由于LODGING$MANAGER是一個非唯一性的索引,數據庫不能對它執行索引唯一掃描.

由于SQL返回LODGING列,而它并不存在于LODGING$MANAGER索引中, 所以在索引范圍查詢后會執行一個通過ROWID訪問表的操作.

WHERE子句中, 假如索引列所對應的值的第一個字符由通配符(WILDCARD)開始, 索引將不被采用.

SELECT LODGING

FROM LODGING

WHERE MANAGER LIKE ‘%HANMAN';

在這種情況下,ORACLE將使用全表掃描. 27. 基礎表的選擇

基礎表(Driving Table)是指被最先訪問的表(通常以全表掃描的方式被訪問). 根據優化器的不同, SQL語句中基礎表的選擇是不一樣的.

假如你使用的是CBO (COST BASED OPTIMIZER),優化器會檢查SQL語句中的每個表的物理大小,索引的狀態,然后選用花費最低的執行路徑.

假如你用RBO (RULE BASED OPTIMIZER) , 并且所有的連接條件都有索引對應, 在這種情況下, 基礎表就是FROM 子句中列在最后的那個表.

舉例:

SELECT A.NAME , B.MANAGER

FROM WORKER A,

LODGING B

WHERE A.LODGING = B.LODING;

由于LODGING表的LODING列上有一個索引, 而且WORKER表中沒有相比較的索引, WORKER表將被作為查詢中的基礎表.

28. 多個平等的索引

當SQL語句的執行路徑可以使用分布在多個表上的多個索引時, ORACLE會同時使用多個索引并在運行時對它們的記錄進行合并, 檢索出僅對全部索引有效的記錄.

在ORACLE選擇執行路徑時,唯一性索引的等級高于非唯一性索引. 然而這個規則只有當WHERE子句中索引列和常量比較才有效.假如索引列和其他表的索引類相比較. 這種子句在優化器中的等級是非常低的.

假如不同表中兩個想同等級的索引將被引用, FROM子句中表的順序將決定哪個會被率先使用. FROM子句中最后的表的索引將有最高的優先級.

假如相同表中兩個想同等級的索引將被引用, WHERE子句中最先被引用的索引將有最高的優先級.

舉例:

DEPTNO上有一個非唯一性索引,EMP_CAT也有一個非唯一性索引.

SELECT ENAME,

FROM EMP

WHERE DEPT_NO = 20

AND EMP_CAT = ‘A';

這里,DEPTNO索引將被最先檢索,然后同EMP_CAT索引檢索出的記錄進行合并. 執行路徑如下:

TABLE ACCESS BY ROWID ON EMP

AND-EQUAL

INDEX RANGE SCAN ON DEPT_IDX

INDEX RANGE SCAN ON CAT_IDX

29. 等式比較和范圍比較

當WHERE子句中有索引列, ORACLE不能合并它們,ORACLE將用范圍比較.

舉例:

DEPTNO上有一個非唯一性索引,EMP_CAT也有一個非唯一性索引.

SELECT ENAME

FROM EMP

WHERE DEPTNO > 20

AND EMP_CAT = ‘A';

這里只有EMP_CAT索引被用到,然后所有的記錄將逐條與DEPTNO條件進行比較. 執行路徑如下:

TABLE ACCESS BY ROWID ON EMP

INDEX RANGE SCAN ON CAT_IDX

30. 不明確的索引等級



當ORACLE無法判定索引的等級高低差別,優化器將只使用一個索引,它就是在WHERE子句中被列在最前面的.

舉例:

DEPTNO上有一個非唯一性索引,EMP_CAT也有一個非唯一性索引.

SELECT ENAME

FROM EMP

WHERE DEPTNO > 20

AND EMP_CAT > ‘A';

這里, ORACLE只用到了DEPT_NO索引. 執行路徑如下:

TABLE ACCESS BY ROWID ON EMP

INDEX RANGE SCAN ON DEPT_IDX

譯者按: 我們來試一下以下這種情況:

SQL> select index_name, uniqueness from user_indexes where table_name = 'EMP';

INDEX_NAME UNIQUENES

------------------------------ ---------

EMPNO UNIQUE

EMPTYPE NONUNIQUE

SQL> select * from emp where empno >= 2 and emp_type = 'A' ;

no rows selected

Execution Plan

----------------------------------------------------------

0 SELECT STATEMENT Optimizer=CHOOSE

1 0 TABLE ACCESS (BY INDEX ROWID) OF 'EMP'

2 1 INDEX (RANGE SCAN) OF 'EMPTYPE' (NON-UNIQUE)

雖然EMPNO是唯一性索引,但是由于它所做的是范圍比較, 等級要比非唯一性索引的等式比較低!
26. 索引的操作

ORACLE對索引有兩種訪問模式.

索引唯一掃描 ( INDEX UNIQUE SCAN)

大多數情況下, 優化器通過WHERE子句訪問INDEX.

例如: 表LODGING有兩個索引 : 建立在LODGING列上的唯一性索引LODGING_PK和建立在MANAGER列上的非唯一性索引LODGING$MANAGER.

SELECT *

FROM LODGING

WHERE LODGING = ‘ROSE HILL';

在內部 , 上述SQL將被分成兩步執行, 首先 , LODGING_PK 索引將通過索引唯一掃描的方式被訪問 , 獲得相對應的ROWID, 通過ROWID訪問表的方式 執行下一步檢索.

假如被檢索返回的列包括在INDEX列中,ORACLE將不執行第二步的處理(通過ROWID訪問表). 因為檢索數據保存在索引中, 單單訪問索引就可以完全滿足查詢結果.

下面SQL只需要INDEX UNIQUE SCAN 操作.

SELECT LODGING

FROM LODGING

WHERE LODGING = ‘ROSE HILL';

索引范圍查詢(INDEX RANGE SCAN)

適用于兩種情況:

1. 基于一個范圍的檢索

2. 基于非唯一性索引的檢索

例1:

SELECT LODGING

FROM LODGING

WHERE LODGING LIKE ‘M%';

WHERE子句條件包括一系列值, ORACLE將通過索引范圍查詢的方式查詢LODGING_PK . 由于索引范圍查詢將返回一組值, 它的效率就要比索引唯一掃描低一些.

例2:

SELECT LODGING

FROM LODGING

WHERE MANAGER = ‘BILL GATES';

這個SQL的執行分兩步, LODGING$MANAGER的索引范圍查詢(得到所有符合條件記錄的ROWID) 和下一步同過ROWID訪問表得到LODGING列的值. 由于LODGING$MANAGER是一個非唯一性的索引,數據庫不能對它執行索引唯一掃描.

由于SQL返回LODGING列,而它并不存在于LODGING$MANAGER索引中, 所以在索引范圍查詢后會執行一個通過ROWID訪問表的操作.

WHERE子句中, 假如索引列所對應的值的第一個字符由通配符(WILDCARD)開始, 索引將不被采用.

SELECT LODGING

FROM LODGING

WHERE MANAGER LIKE ‘%HANMAN';

在這種情況下,ORACLE將使用全表掃描. 27. 基礎表的選擇

基礎表(Driving Table)是指被最先訪問的表(通常以全表掃描的方式被訪問). 根據優化器的不同, SQL語句中基礎表的選擇是不一樣的.

假如你使用的是CBO (COST BASED OPTIMIZER),優化器會檢查SQL語句中的每個表的物理大小,索引的狀態,然后選用花費最低的執行路徑.

假如你用RBO (RULE BASED OPTIMIZER) , 并且所有的連接條件都有索引對應, 在這種情況下, 基礎表就是FROM 子句中列在最后的那個表.

舉例:

SELECT A.NAME , B.MANAGER

FROM WORKER A,

LODGING B

WHERE A.LODGING = B.LODING;

由于LODGING表的LODING列上有一個索引, 而且WORKER表中沒有相比較的索引, WORKER表將被作為查詢中的基礎表.

28. 多個平等的索引

當SQL語句的執行路徑可以使用分布在多個表上的多個索引時, ORACLE會同時使用多個索引并在運行時對它們的記錄進行合并, 檢索出僅對全部索引有效的記錄.

在ORACLE選擇執行路徑時,唯一性索引的等級高于非唯一性索引. 然而這個規則只有當WHERE子句中索引列和常量比較才有效.假如索引列和其他表的索引類相比較. 這種子句在優化器中的等級是非常低的.

假如不同表中兩個想同等級的索引將被引用, FROM子句中表的順序將決定哪個會被率先使用. FROM子句中最后的表的索引將有最高的優先級.

假如相同表中兩個想同等級的索引將被引用, WHERE子句中最先被引用的索引將有最高的優先級.

舉例:

DEPTNO上有一個非唯一性索引,EMP_CAT也有一個非唯一性索引.

SELECT ENAME,

FROM EMP

WHERE DEPT_NO = 20

AND EMP_CAT = ‘A';

這里,DEPTNO索引將被最先檢索,然后同EMP_CAT索引檢索出的記錄進行合并. 執行路徑如下:

TABLE ACCESS BY ROWID ON EMP

AND-EQUAL

INDEX RANGE SCAN ON DEPT_IDX

INDEX RANGE SCAN ON CAT_IDX

29. 等式比較和范圍比較

當WHERE子句中有索引列, ORACLE不能合并它們,ORACLE將用范圍比較.

舉例:

DEPTNO上有一個非唯一性索引,EMP_CAT也有一個非唯一性索引.

SELECT ENAME

FROM EMP

WHERE DEPTNO > 20

AND EMP_CAT = ‘A';

這里只有EMP_CAT索引被用到,然后所有的記錄將逐條與DEPTNO條件進行比較. 執行路徑如下:

TABLE ACCESS BY ROWID ON EMP

INDEX RANGE SCAN ON CAT_IDX

30. 不明確的索引等級



當ORACLE無法判定索引的等級高低差別,優化器將只使用一個索引,它就是在WHERE子句中被列在最前面的.

舉例:

DEPTNO上有一個非唯一性索引,EMP_CAT也有一個非唯一性索引.

SELECT ENAME

FROM EMP

WHERE DEPTNO > 20

AND EMP_CAT > ‘A';

這里, ORACLE只用到了DEPT_NO索引. 執行路徑如下:

TABLE ACCESS BY ROWID ON EMP

INDEX RANGE SCAN ON DEPT_IDX

譯者按: 我們來試一下以下這種情況:

SQL> select index_name, uniqueness from user_indexes where table_name = 'EMP';

INDEX_NAME UNIQUENES

------------------------------ ---------

EMPNO UNIQUE

EMPTYPE NONUNIQUE

SQL> select * from emp where empno >= 2 and emp_type = 'A' ;

no rows selected

Execution Plan

----------------------------------------------------------

0 SELECT STATEMENT Optimizer=CHOOSE

1 0 TABLE ACCESS (BY INDEX ROWID) OF 'EMP'

2 1 INDEX (RANGE SCAN) OF 'EMPTYPE' (NON-UNIQUE)

雖然EMPNO是唯一性索引,但是由于它所做的是范圍比較, 等級要比非唯一性索引的等式比較低!
26. 索引的操作

ORACLE對索引有兩種訪問模式.

索引唯一掃描 ( INDEX UNIQUE SCAN)

大多數情況下, 優化器通過WHERE子句訪問INDEX.

例如: 表LODGING有兩個索引 : 建立在LODGING列上的唯一性索引LODGING_PK和建立在MANAGER列上的非唯一性索引LODGING$MANAGER.

SELECT *

FROM LODGING

WHERE LODGING = ‘ROSE HILL';

在內部 , 上述SQL將被分成兩步執行, 首先 , LODGING_PK 索引將通過索引唯一掃描的方式被訪問 , 獲得相對應的ROWID, 通過ROWID訪問表的方式 執行下一步檢索.

假如被檢索返回的列包括在INDEX列中,ORACLE將不執行第二步的處理(通過ROWID訪問表). 因為檢索數據保存在索引中, 單單訪問索引就可以完全滿足查詢結果.

下面SQL只需要INDEX UNIQUE SCAN 操作.

SELECT LODGING

FROM LODGING

WHERE LODGING = ‘ROSE HILL';

索引范圍查詢(INDEX RANGE SCAN)

適用于兩種情況:

1. 基于一個范圍的檢索

2. 基于非唯一性索引的檢索

例1:

SELECT LODGING

FROM LODGING

WHERE LODGING LIKE ‘M%';

WHERE子句條件包括一系列值, ORACLE將通過索引范圍查詢的方式查詢LODGING_PK . 由于索引范圍查詢將返回一組值, 它的效率就要比索引唯一掃描低一些.

例2:

SELECT LODGING

FROM LODGING

WHERE MANAGER = ‘BILL GATES';

這個SQL的執行分兩步, LODGING$MANAGER的索引范圍查詢(得到所有符合條件記錄的ROWID) 和下一步同過ROWID訪問表得到LODGING列的值. 由于LODGING$MANAGER是一個非唯一性的索引,數據庫不能對它執行索引唯一掃描.

由于SQL返回LODGING列,而它并不存在于LODGING$MANAGER索引中, 所以在索引范圍查詢后會執行一個通過ROWID訪問表的操作.

WHERE子句中, 假如索引列所對應的值的第一個字符由通配符(WILDCARD)開始, 索引將不被采用.

SELECT LODGING

FROM LODGING

WHERE MANAGER LIKE ‘%HANMAN';

在這種情況下,ORACLE將使用全表掃描. 27. 基礎表的選擇

基礎表(Driving Table)是指被最先訪問的表(通常以全表掃描的方式被訪問). 根據優化器的不同, SQL語句中基礎表的選擇是不一樣的.

假如你使用的是CBO (COST BASED OPTIMIZER),優化器會檢查SQL語句中的每個表的物理大小,索引的狀態,然后選用花費最低的執行路徑.

假如你用RBO (RULE BASED OPTIMIZER) , 并且所有的連接條件都有索引對應, 在這種情況下, 基礎表就是FROM 子句中列在最后的那個表.

舉例:

SELECT A.NAME , B.MANAGER

FROM WORKER A,

LODGING B

WHERE A.LODGING = B.LODING;

由于LODGING表的LODING列上有一個索引, 而且WORKER表中沒有相比較的索引, WORKER表將被作為查詢中的基礎表.

28. 多個平等的索引

當SQL語句的執行路徑可以使用分布在多個表上的多個索引時, ORACLE會同時使用多個索引并在運行時對它們的記錄進行合并, 檢索出僅對全部索引有效的記錄.

在ORACLE選擇執行路徑時,唯一性索引的等級高于非唯一性索引. 然而這個規則只有當WHERE子句中索引列和常量比較才有效.假如索引列和其他表的索引類相比較. 這種子句在優化器中的等級是非常低的.

假如不同表中兩個想同等級的索引將被引用, FROM子句中表的順序將決定哪個會被率先使用. FROM子句中最后的表的索引將有最高的優先級.

假如相同表中兩個想同等級的索引將被引用, WHERE子句中最先被引用的索引將有最高的優先級.

舉例:

DEPTNO上有一個非唯一性索引,EMP_CAT也有一個非唯一性索引.

SELECT ENAME,

FROM EMP

WHERE DEPT_NO = 20

AND EMP_CAT = ‘A';

這里,DEPTNO索引將被最先檢索,然后同EMP_CAT索引檢索出的記錄進行合并. 執行路徑如下:

TABLE ACCESS BY ROWID ON EMP

AND-EQUAL

INDEX RANGE SCAN ON DEPT_IDX

INDEX RANGE SCAN ON CAT_IDX

29. 等式比較和范圍比較

當WHERE子句中有索引列, ORACLE不能合并它們,ORACLE將用范圍比較.

舉例:

DEPTNO上有一個非唯一性索引,EMP_CAT也有一個非唯一性索引.

SELECT ENAME

FROM EMP

WHERE DEPTNO > 20

AND EMP_CAT = ‘A';

這里只有EMP_CAT索引被用到,然后所有的記錄將逐條與DEPTNO條件進行比較. 執行路徑如下:

TABLE ACCESS BY ROWID ON EMP

INDEX RANGE SCAN ON CAT_IDX

30. 不明確的索引等級



當ORACLE無法判定索引的等級高低差別,優化器將只使用一個索引,它就是在WHERE子句中被列在最前面的.

舉例:

DEPTNO上有一個非唯一性索引,EMP_CAT也有一個非唯一性索引.

SELECT ENAME

FROM EMP

WHERE DEPTNO > 20

AND EMP_CAT > ‘A';

這里, ORACLE只用到了DEPT_NO索引. 執行路徑如下:

TABLE ACCESS BY ROWID ON EMP

INDEX RANGE SCAN ON DEPT_IDX

譯者按: 我們來試一下以下這種情況:

SQL> select index_name, uniqueness from user_indexes where table_name = 'EMP';

INDEX_NAME UNIQUENES

------------------------------ ---------

EMPNO UNIQUE

EMPTYPE NONUNIQUE

SQL> select * from emp where empno >= 2 and emp_type = 'A' ;

no rows selected

Execution Plan

----------------------------------------------------------

0 SELECT STATEMENT Optimizer=CHOOSE

1 0 TABLE ACCESS (BY INDEX ROWID) OF 'EMP'

2 1 INDEX (RANGE SCAN) OF 'EMPTYPE' (NON-UNIQUE)

雖然EMPNO是唯一性索引,但是由于它所做的是范圍比較, 等級要比非唯一性索引的等式比較低!
26. 索引的操作

ORACLE對索引有兩種訪問模式.

索引唯一掃描 ( INDEX UNIQUE SCAN)

大多數情況下, 優化器通過WHERE子句訪問INDEX.

例如: 表LODGING有兩個索引 : 建立在LODGING列上的唯一性索引LODGING_PK和建立在MANAGER列上的非唯一性索引LODGING$MANAGER.

SELECT *

FROM LODGING

WHERE LODGING = ‘ROSE HILL';

在內部 , 上述SQL將被分成兩步執行, 首先 , LODGING_PK 索引將通過索引唯一掃描的方式被訪問 , 獲得相對應的ROWID, 通過ROWID訪問表的方式 執行下一步檢索.

假如被檢索返回的列包括在INDEX列中,ORACLE將不執行第二步的處理(通過ROWID訪問表). 因為檢索數據保存在索引中, 單單訪問索引就可以完全滿足查詢結果.

下面SQL只需要INDEX UNIQUE SCAN 操作.

SELECT LODGING

FROM LODGING

WHERE LODGING = ‘ROSE HILL';

索引范圍查詢(INDEX RANGE SCAN)

適用于兩種情況:

1. 基于一個范圍的檢索

2. 基于非唯一性索引的檢索

例1:

SELECT LODGING

FROM LODGING

WHERE LODGING LIKE ‘M%';

WHERE子句條件包括一系列值, ORACLE將通過索引范圍查詢的方式查詢LODGING_PK . 由于索引范圍查詢將返回一組值, 它的效率就要比索引唯一掃描低一些.

例2:

SELECT LODGING

FROM LODGING

WHERE MANAGER = ‘BILL GATES';

這個SQL的執行分兩步, LODGING$MANAGER的索引范圍查詢(得到所有符合條件記錄的ROWID) 和下一步同過ROWID訪問表得到LODGING列的值. 由于LODGING$MANAGER是一個非唯一性的索引,數據庫不能對它執行索引唯一掃描.

由于SQL返回LODGING列,而它并不存在于LODGING$MANAGER索引中, 所以在索引范圍查詢后會執行一個通過ROWID訪問表的操作.

WHERE子句中, 假如索引列所對應的值的第一個字符由通配符(WILDCARD)開始, 索引將不被采用.

SELECT LODGING

FROM LODGING

WHERE MANAGER LIKE ‘%HANMAN';

在這種情況下,ORACLE將使用全表掃描. 27. 基礎表的選擇

基礎表(Driving Table)是指被最先訪問的表(通常以全表掃描的方式被訪問). 根據優化器的不同, SQL語句中基礎表的選擇是不一樣的.

假如你使用的是CBO (COST BASED OPTIMIZER),優化器會檢查SQL語句中的每個表的物理大小,索引的狀態,然后選用花費最低的執行路徑.

假如你用RBO (RULE BASED OPTIMIZER) , 并且所有的連接條件都有索引對應, 在這種情況下, 基礎表就是FROM 子句中列在最后的那個表.

舉例:

SELECT A.NAME , B.MANAGER

FROM WORKER A,

LODGING B

WHERE A.LODGING = B.LODING;

由于LODGING表的LODING列上有一個索引, 而且WORKER表中沒有相比較的索引, WORKER表將被作為查詢中的基礎表.

28. 多個平等的索引

當SQL語句的執行路徑可以使用分布在多個表上的多個索引時, ORACLE會同時使用多個索引并在運行時對它們的記錄進行合并, 檢索出僅對全部索引有效的記錄.

在ORACLE選擇執行路徑時,唯一性索引的等級高于非唯一性索引. 然而這個規則只有當WHERE子句中索引列和常量比較才有效.假如索引列和其他表的索引類相比較. 這種子句在優化器中的等級是非常低的.

假如不同表中兩個想同等級的索引將被引用, FROM子句中表的順序將決定哪個會被率先使用. FROM子句中最后的表的索引將有最高的優先級.

假如相同表中兩個想同等級的索引將被引用, WHERE子句中最先被引用的索引將有最高的優先級.

舉例:

DEPTNO上有一個非唯一性索引,EMP_CAT也有一個非唯一性索引.

SELECT ENAME,

FROM EMP

WHERE DEPT_NO = 20

AND EMP_CAT = ‘A';

這里,DEPTNO索引將被最先檢索,然后同EMP_CAT索引檢索出的記錄進行合并. 執行路徑如下:

TABLE ACCESS BY ROWID ON EMP

AND-EQUAL

INDEX RANGE SCAN ON DEPT_IDX

INDEX RANGE SCAN ON CAT_IDX

29. 等式比較和范圍比較

當WHERE子句中有索引列, ORACLE不能合并它們,ORACLE將用范圍比較.

舉例:

DEPTNO上有一個非唯一性索引,EMP_CAT也有一個非唯一性索引.

SELECT ENAME

FROM EMP

WHERE DEPTNO > 20

AND EMP_CAT = ‘A';

這里只有EMP_CAT索引被用到,然后所有的記錄將逐條與DEPTNO條件進行比較. 執行路徑如下:

TABLE ACCESS BY ROWID ON EMP

INDEX RANGE SCAN ON CAT_IDX

30. 不明確的索引等級



當ORACLE無法判定索引的等級高低差別,優化器將只使用一個索引,它就是在WHERE子句中被列在最前面的.

舉例:

DEPTNO上有一個非唯一性索引,EMP_CAT也有一個非唯一性索引.

SELECT ENAME

FROM EMP

WHERE DEPTNO > 20

AND EMP_CAT > ‘A';

這里, ORACLE只用到了DEPT_NO索引. 執行路徑如下:

TABLE ACCESS BY ROWID ON EMP

INDEX RANGE SCAN ON DEPT_IDX

譯者按: 我們來試一下以下這種情況:

SQL> select index_name, uniqueness from user_indexes where table_name = 'EMP';

INDEX_NAME UNIQUENES

------------------------------ ---------

EMPNO UNIQUE

EMPTYPE NONUNIQUE

SQL> select * from emp where empno >= 2 and emp_type = 'A' ;

no rows selected

Execution Plan

----------------------------------------------------------

0 SELECT STATEMENT Optimizer=CHOOSE

1 0 TABLE ACCESS (BY INDEX ROWID) OF 'EMP'

2 1 INDEX (RANGE SCAN) OF 'EMPTYPE' (NON-UNIQUE)

雖然EMPNO是唯一性索引,但是由于它所做的是范圍比較, 等級要比非唯一性索引的等式比較低!
26. 索引的操作

ORACLE對索引有兩種訪問模式.

索引唯一掃描 ( INDEX UNIQUE SCAN)

大多數情況下, 優化器通過WHERE子句訪問INDEX.

例如: 表LODGING有兩個索引 : 建立在LODGING列上的唯一性索引LODGING_PK和建立在MANAGER列上的非唯一性索引LODGING$MANAGER.

SELECT *

FROM LODGING

WHERE LODGING = ‘ROSE HILL';

在內部 , 上述SQL將被分成兩步執行, 首先 , LODGING_PK 索引將通過索引唯一掃描的方式被訪問 , 獲得相對應的ROWID, 通過ROWID訪問表的方式 執行下一步檢索.

假如被檢索返回的列包括在INDEX列中,ORACLE將不執行第二步的處理(通過ROWID訪問表). 因為檢索數據保存在索引中, 單單訪問索引就可以完全滿足查詢結果.

下面SQL只需要INDEX UNIQUE SCAN 操作.

SELECT LODGING

FROM LODGING

WHERE LODGING = ‘ROSE HILL';

索引范圍查詢(INDEX RANGE SCAN)

適用于兩種情況:

1. 基于一個范圍的檢索

2. 基于非唯一性索引的檢索

例1:

SELECT LODGING

FROM LODGING

WHERE LODGING LIKE ‘M%';

WHERE子句條件包括一系列值, ORACLE將通過索引范圍查詢的方式查詢LODGING_PK . 由于索引范圍查詢將返回一組值, 它的效率就要比索引唯一掃描低一些.

例2:

SELECT LODGING

FROM LODGING

WHERE MANAGER = ‘BILL GATES';

這個SQL的執行分兩步, LODGING$MANAGER的索引范圍查詢(得到所有符合條件記錄的ROWID) 和下一步同過ROWID訪問表得到LODGING列的值. 由于LODGING$MANAGER是一個非唯一性的索引,數據庫不能對它執行索引唯一掃描.

由于SQL返回LODGING列,而它并不存在于LODGING$MANAGER索引中, 所以在索引范圍查詢后會執行一個通過ROWID訪問表的操作.

WHERE子句中, 假如索引列所對應的值的第一個字符由通配符(WILDCARD)開始, 索引將不被采用.

SELECT LODGING

FROM LODGING

WHERE MANAGER LIKE ‘%HANMAN';

在這種情況下,ORACLE將使用全表掃描. 27. 基礎表的選擇

基礎表(Driving Table)是指被最先訪問的表(通常以全表掃描的方式被訪問). 根據優化器的不同, SQL語句中基礎表的選擇是不一樣的.

假如你使用的是CBO (COST BASED OPTIMIZER),優化器會檢查SQL語句中的每個表的物理大小,索引的狀態,然后選用花費最低的執行路徑.

假如你用RBO (RULE BASED OPTIMIZER) , 并且所有的連接條件都有索引對應, 在這種情況下, 基礎表就是FROM 子句中列在最后的那個表.

舉例:

SELECT A.NAME , B.MANAGER

FROM WORKER A,

LODGING B

WHERE A.LODGING = B.LODING;

由于LODGING表的LODING列上有一個索引, 而且WORKER表中沒有相比較的索引, WORKER表將被作為查詢中的基礎表.

28. 多個平等的索引

當SQL語句的執行路徑可以使用分布在多個表上的多個索引時, ORACLE會同時使用多個索引并在運行時對它們的記錄進行合并, 檢索出僅對全部索引有效的記錄.

在ORACLE選擇執行路徑時,唯一性索引的等級高于非唯一性索引. 然而這個規則只有當WHERE子句中索引列和常量比較才有效.假如索引列和其他表的索引類相比較. 這種子句在優化器中的等級是非常低的.

假如不同表中兩個想同等級的索引將被引用, FROM子句中表的順序將決定哪個會被率先使用. FROM子句中最后的表的索引將有最高的優先級.

假如相同表中兩個想同等級的索引將被引用, WHERE子句中最先被引用的索引將有最高的優先級.

舉例:

DEPTNO上有一個非唯一性索引,EMP_CAT也有一個非唯一性索引.

SELECT ENAME,

FROM EMP

WHERE DEPT_NO = 20

AND EMP_CAT = ‘A';

這里,DEPTNO索引將被最先檢索,然后同EMP_CAT索引檢索出的記錄進行合并. 執行路徑如下:

TABLE ACCESS BY ROWID ON EMP

AND-EQUAL

INDEX RANGE SCAN ON DEPT_IDX

INDEX RANGE SCAN ON CAT_IDX

29. 等式比較和范圍比較

當WHERE子句中有索引列, ORACLE不能合并它們,ORACLE將用范圍比較.

舉例:

DEPTNO上有一個非唯一性索引,EMP_CAT也有一個非唯一性索引.

SELECT ENAME

FROM EMP

WHERE DEPTNO > 20

AND EMP_CAT = ‘A';

這里只有EMP_CAT索引被用到,然后所有的記錄將逐條與DEPTNO條件進行比較. 執行路徑如下:

TABLE ACCESS BY ROWID ON EMP

INDEX RANGE SCAN ON CAT_IDX

30. 不明確的索引等級



當ORACLE無法判定索引的等級高低差別,優化器將只使用一個索引,它就是在WHERE子句中被列在最前面的.

舉例:

DEPTNO上有一個非唯一性索引,EMP_CAT也有一個非唯一性索引.

SELECT ENAME

FROM EMP

WHERE DEPTNO > 20

AND EMP_CAT > ‘A';

這里, ORACLE只用到了DEPT_NO索引. 執行路徑如下:

TABLE ACCESS BY ROWID ON EMP

INDEX RANGE SCAN ON DEPT_IDX

譯者按: 我們來試一下以下這種情況:

SQL> select index_name, uniqueness from user_indexes where table_name = 'EMP';

INDEX_NAME UNIQUENES

------------------------------ ---------

EMPNO UNIQUE

EMPTYPE NONUNIQUE

SQL> select * from emp where empno >= 2 and emp_type = 'A' ;

no rows selected

Execution Plan

----------------------------------------------------------

0 SELECT STATEMENT Optimizer=CHOOSE

1 0 TABLE ACCESS (BY INDEX ROWID) OF 'EMP'

2 1 INDEX (RANGE SCAN) OF 'EMPTYPE' (NON-UNIQUE)

雖然EMPNO是唯一性索引,但是由于它所做的是范圍比較, 等級要比非唯一性索引的等式比較低!


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 酉阳| 松溪县| 垫江县| 东光县| 黔南| 马龙县| 平湖市| 丹巴县| 剑河县| 舞钢市| 延吉市| 永吉县| 饶河县| 庆元县| 莆田市| 威海市| 临江市| 凌源市| 扬州市| 察隅县| 商丘市| 如皋市| 五家渠市| 会昌县| 云林县| 上饶县| 永嘉县| 司法| 金山区| 万安县| 盐城市| 莎车县| 芦山县| 大冶市| 乐昌市| 凌源市| 河北省| 满城县| 舒兰市| 巴东县| 郴州市|