46. 連接多個掃描
如果你對一個列和一組有限的值進行比較, 優(yōu)化器可能執(zhí)行多次掃描并對結果進行合并連接.
舉例:
SELECT *
FROM LODGING
WHERE MANAGER IN (‘BILL GATES’,’KEN MULLER’);
優(yōu)化器可能將它轉換成以下形式
SELECT *
FROM LODGING
WHERE MANAGER = ‘BILL GATES’
OR MANAGER = ’KEN MULLER’;
當選擇執(zhí)行路徑時, 優(yōu)化器可能對每個條件采用LODGING$MANAGER上的索引范圍掃描. 返回的ROWID用來訪問LODGING表的記錄 (通過TABLE ACCESS BY ROWID 的方式). 最后兩組記錄以連接(CONCATENATION)的形式被組合成一個單一的集合.
Explain Plan :
SELECT STATEMENT Optimizer=CHOOSE
CONCATENATION
TABLE ACCESS (BY INDEX ROWID) OF LODGING
INDEX (RANGE SCAN ) OF LODGING$MANAGER (NON-UNIQUE)
TABLE ACCESS (BY INDEX ROWID) OF LODGING
INDEX (RANGE SCAN ) OF LODGING$MANAGER (NON-UNIQUE)
譯者按:
本節(jié)和第37節(jié)似乎有矛盾之處.
47. CBO下使用更具選擇性的索引
基于成本的優(yōu)化器(CBO, Cost-Based Optimizer)對索引的選擇性進行判斷來決定索引的使用是否能提高效率.
如果索引有很高的選擇性, 那就是說對于每個不重復的索引鍵值,只對應數量很少的記錄.
比如, 表中共有100條記錄而其中有80個不重復的索引鍵值. 這個索引的選擇性就是80/100 = 0.8 . 選擇性越高, 通過索引鍵值檢索出的記錄就越少.
如果索引的選擇性很低, 檢索數據就需要大量的索引范圍查詢操作和ROWID 訪問表的
操作. 也許會比全表掃描的效率更低.
譯者按:
下列經驗請參閱:
a. 如果檢索數據量超過30%的表中記錄數.使用索引將沒有顯著的效率提高.
b. 在特定情況下, 使用索引也許會比全表掃描慢, 但這是同一個數量級上的
區(qū)別. 而通常情況下,使用索引比全表掃描要塊幾倍乃至幾千倍!
48. 避免使用耗費資源的操作
帶有DISTINCT,UNION,MINUS,INTERSECT,ORDER BY的SQL語句會啟動SQL引擎
執(zhí)行耗費資源的排序(SORT)功能. DISTINCT需要一次排序操作, 而其他的至少需要執(zhí)行兩次排序.
例如,一個UNION查詢,其中每個查詢都帶有GROUP BY子句, GROUP BY會觸發(fā)嵌入排序(NESTED SORT) ; 這樣, 每個查詢需要執(zhí)行一次排序, 然后在執(zhí)行UNION時, 又一個排序(SORT UNIQUE)操作被執(zhí)行而且它只能在前面的嵌入排序結束后才能開始執(zhí)行. 嵌入的排序的深度會大大影響查詢的效率.
通常, 帶有UNION, MINUS , INTERSECT的SQL語句都可以用其他方式重寫.
譯者按:
如果你的數據庫的SORT_AREA_SIZE調配得好, 使用UNION , MINUS, INTERSECT也是可以考慮的, 畢竟它們的可讀性很強
49. 優(yōu)化GROUP BY
提高GROUP BY 語句的效率, 可以通過將不需要的記錄在GROUP BY 之前過濾掉.下面兩個查詢返回相同結果但第二個明顯就快了許多.
低效:
SELECT JOB , AVG(SAL)
FROM EMP
GROUP JOB
HAVING JOB = ‘PRESIDENT’
OR JOB = ‘MANAGER’
高效:
SELECT JOB , AVG(SAL)
FROM EMP
WHERE JOB = ‘PRESIDENT’
OR JOB = ‘MANAGER’
GROUP JOB
如果你對一個列和一組有限的值進行比較, 優(yōu)化器可能執(zhí)行多次掃描并對結果進行合并連接.
舉例:
SELECT *
FROM LODGING
WHERE MANAGER IN (‘BILL GATES’,’KEN MULLER’);
優(yōu)化器可能將它轉換成以下形式
SELECT *
FROM LODGING
WHERE MANAGER = ‘BILL GATES’
OR MANAGER = ’KEN MULLER’;
當選擇執(zhí)行路徑時, 優(yōu)化器可能對每個條件采用LODGING$MANAGER上的索引范圍掃描. 返回的ROWID用來訪問LODGING表的記錄 (通過TABLE ACCESS BY ROWID 的方式). 最后兩組記錄以連接(CONCATENATION)的形式被組合成一個單一的集合.
Explain Plan :
SELECT STATEMENT Optimizer=CHOOSE
CONCATENATION
TABLE ACCESS (BY INDEX ROWID) OF LODGING
INDEX (RANGE SCAN ) OF LODGING$MANAGER (NON-UNIQUE)
TABLE ACCESS (BY INDEX ROWID) OF LODGING
INDEX (RANGE SCAN ) OF LODGING$MANAGER (NON-UNIQUE)
譯者按:
本節(jié)和第37節(jié)似乎有矛盾之處.
47. CBO下使用更具選擇性的索引
基于成本的優(yōu)化器(CBO, Cost-Based Optimizer)對索引的選擇性進行判斷來決定索引的使用是否能提高效率.
如果索引有很高的選擇性, 那就是說對于每個不重復的索引鍵值,只對應數量很少的記錄.
比如, 表中共有100條記錄而其中有80個不重復的索引鍵值. 這個索引的選擇性就是80/100 = 0.8 . 選擇性越高, 通過索引鍵值檢索出的記錄就越少.
如果索引的選擇性很低, 檢索數據就需要大量的索引范圍查詢操作和ROWID 訪問表的
操作. 也許會比全表掃描的效率更低.
譯者按:
下列經驗請參閱:
a. 如果檢索數據量超過30%的表中記錄數.使用索引將沒有顯著的效率提高.
b. 在特定情況下, 使用索引也許會比全表掃描慢, 但這是同一個數量級上的
區(qū)別. 而通常情況下,使用索引比全表掃描要塊幾倍乃至幾千倍!
48. 避免使用耗費資源的操作
帶有DISTINCT,UNION,MINUS,INTERSECT,ORDER BY的SQL語句會啟動SQL引擎
執(zhí)行耗費資源的排序(SORT)功能. DISTINCT需要一次排序操作, 而其他的至少需要執(zhí)行兩次排序.
例如,一個UNION查詢,其中每個查詢都帶有GROUP BY子句, GROUP BY會觸發(fā)嵌入排序(NESTED SORT) ; 這樣, 每個查詢需要執(zhí)行一次排序, 然后在執(zhí)行UNION時, 又一個排序(SORT UNIQUE)操作被執(zhí)行而且它只能在前面的嵌入排序結束后才能開始執(zhí)行. 嵌入的排序的深度會大大影響查詢的效率.
通常, 帶有UNION, MINUS , INTERSECT的SQL語句都可以用其他方式重寫.
譯者按:
如果你的數據庫的SORT_AREA_SIZE調配得好, 使用UNION , MINUS, INTERSECT也是可以考慮的, 畢竟它們的可讀性很強
49. 優(yōu)化GROUP BY
提高GROUP BY 語句的效率, 可以通過將不需要的記錄在GROUP BY 之前過濾掉.下面兩個查詢返回相同結果但第二個明顯就快了許多.
低效:
SELECT JOB , AVG(SAL)
FROM EMP
GROUP JOB
HAVING JOB = ‘PRESIDENT’
OR JOB = ‘MANAGER’
高效:
SELECT JOB , AVG(SAL)
FROM EMP
WHERE JOB = ‘PRESIDENT’
OR JOB = ‘MANAGER’
GROUP JOB