Oracle SQL性能優(yōu)化系列 (十四) 完結(jié)篇
46. 連接多個(gè)掃描假如你對(duì)一個(gè)列和一組有限的值進(jìn)行比較, 優(yōu)化器可能執(zhí)行多次掃描并對(duì)結(jié)果進(jìn)行合并連接.舉例:SELECT * FROM LODGINGWHERE MANAGER IN (‘BILL GATES’,’KEN MULLER’); 優(yōu)化器可能將它轉(zhuǎn)換成以下形式SELECT * FROM LODGINGWHERE MANAGER = ‘BILL GATES’OR MANAGER = ’KEN MULLER’; 當(dāng)選擇執(zhí)行路徑時(shí), 優(yōu)化器可能對(duì)每個(gè)條件采用LODGING$MANAGER上的索引范圍掃描. 返回的ROWID用來(lái)訪問(wèn)LODGING表的記錄 (通過(guò)TABLE access BY ROWID 的方式). 最后兩組記錄以連接(CONCATENATION)的形式被組合成一個(gè)單一的集合. EXPlain Plan : SELECT STATEMENT Optimizer=CHOOSECONCATENATIONTABLE ACCESS (BY INDEX ROWID) OF LODGINGINDEX (RANGE SCAN ) OF LODGING$MANAGER (NON-UNIQUE)TABLE ACCESS (BY INDEX ROWID) OF LODGINGINDEX (RANGE SCAN ) OF LODGING$MANAGER (NON-UNIQUE)譯者按:本節(jié)和第37節(jié)似乎有矛盾之處. 47. CBO下使用更具選擇性的索引基于成本的優(yōu)化器(CBO, Cost-Based Optimizer)對(duì)索引的選擇性進(jìn)行判定來(lái)決定索引的使用是否能提高效率.假如索引有很高的選擇性, 那就是說(shuō)對(duì)于每個(gè)不重復(fù)的索引鍵值,只對(duì)應(yīng)數(shù)量很少的記錄.比如, 表中共有100條記錄而其中有80個(gè)不重復(fù)的索引鍵值. 這個(gè)索引的選擇性就是80/100 = 0.8 . 選擇性越高, 通過(guò)索引鍵值檢索出的記錄就越少. 假如索引的選擇性很低, 檢索數(shù)據(jù)就需要大量的索引范圍查詢操作和ROWID 訪問(wèn)表的操作. 也許會(huì)比全表掃描的效率更低. 譯者按:下列經(jīng)驗(yàn)請(qǐng)參閱:a. 假如檢索數(shù)據(jù)量超過(guò)30%的表中記錄數(shù).使用索引將沒(méi)有顯著的效率提高. b. 在特定情況下, 使用索引也許會(huì)比全表掃描慢, 但這是同一個(gè)數(shù)量級(jí)上的區(qū)別. 而通常情況下,使用索引比全表掃描要塊幾倍乃至幾千倍! 48. 避免使用耗費(fèi)資源的操作帶有DISTINCT,UNION,MINUS,INTERSECT,ORDER BY的SQL語(yǔ)句會(huì)啟動(dòng)SQL引擎執(zhí)行耗費(fèi)資源的排序(SORT)功能. DISTINCT需要一次排序操作, 而其他的至少需要執(zhí)行兩次排序.例如,一個(gè)UNION查詢,其中每個(gè)查詢都帶有GROUP BY子句, GROUP BY會(huì)觸發(fā)嵌入排序(NESTED SORT) ; 這樣, 每個(gè)查詢需要執(zhí)行一次排序, 然后在執(zhí)行UNION時(shí), 又一個(gè)唯一排序(SORT UNIQUE)操作被執(zhí)行而且它只能在前面的嵌入排序結(jié)束后才能開始執(zhí)行. 嵌入的排序的深度會(huì)大大影響查詢的效率.通常, 帶有UNION, MINUS , INTERSECT的SQL語(yǔ)句都可以用其他方式重寫.譯者按:假如你的數(shù)據(jù)庫(kù)的SORT_AREA_SIZE調(diào)配得好, 使用UNION , MINUS, INTERSECT也是可以考慮的, 究竟它們的可讀性很強(qiáng) 49. 優(yōu)化GROUP BY提高GROUP BY 語(yǔ)句的效率, 可以通過(guò)將不需要的記錄在GROUP BY 之前過(guò)濾掉.下面兩個(gè)查詢返回相同結(jié)果但第二個(gè)明顯就快了許多. 低效:SELECT JOB , AVG(SAL)FROM EMPGROUP JOB HAVING JOB = ‘PRESIDENT’OR JOB = ‘MANAGER’高效:SELECT JOB , AVG(SAL)FROM EMPWHERE JOB = ‘PRESIDENT’OR JOB = ‘MANAGER’GROUP JOB 譯者按:本節(jié)和14節(jié)相同. 可略過(guò). 50. 使用日期 當(dāng)使用日期是,需要注重假如有超過(guò)5位小數(shù)加到日期上, 這個(gè)日期會(huì)進(jìn)到下一天! 例如:1.SELECT TO_DATE(‘01-JAN-93’+.99999)FROM DUAL; Returns:’01-JAN-93 23:59:59’2.SELECT TO_DATE(‘01-JAN-93’+.999999)FROM DUAL; Returns:’02-JAN-93 00:00:00’ 譯者按:雖然本節(jié)和SQL性能優(yōu)化沒(méi)有關(guān)系, 但是作者的功力可見(jiàn)一斑 51. 使用顯式的游標(biāo)(CURSORs)使用隱式的游標(biāo),將會(huì)執(zhí)行兩次操作. 第一次檢索記錄, 第二次檢查TOO MANY ROWS 這個(gè)exception . 而顯式游標(biāo)不執(zhí)行第二次操作. 52. 優(yōu)化EXPORT和IMPORT使用較大的BUFFER(比如10MB , 10,240,000)可以提高EXPORT和IMPORT的速度.ORACLE將盡可能地獲取你所指定的內(nèi)存大小,即使在內(nèi)存不滿足,也不會(huì)報(bào)錯(cuò).這個(gè)值至少要和表中最大的列相當(dāng),否則列值會(huì)被截?cái)? 譯者按:可以肯定的是, 增加BUFFER會(huì)大大提高EXPORT , IMPORT的效率. (曾經(jīng)碰到過(guò)一個(gè)CASE, 增加BUFFER后,IMPORT/EXPORT快了10倍!) 作者可能犯了一個(gè)錯(cuò)誤: “這個(gè)值至少要和表中最大的列相當(dāng),否則列值會(huì)被截?cái)? “其中最大的列也許是指最大的記錄大小.關(guān)于EXPORT/IMPORT的優(yōu)化,CSDN論壇中有一些總結(jié)性的貼子,比如關(guān)于BUFFER參數(shù), COMMIT參數(shù)等等, 詳情請(qǐng)查. 53. 分離表和索引總是將你的表和索引建立在不同的表空間內(nèi)(TABLESPACES). 決不要將不屬于ORACLE內(nèi)部系統(tǒng)的對(duì)象存放到SYSTEM表空間里. 同時(shí),確保數(shù)據(jù)表空間和索引表空間置于不同的硬盤上. 譯者按:“同時(shí),確保數(shù)據(jù)表空間和索引表空間置與不同的硬盤上.”可能改為如下更為準(zhǔn)確 “同時(shí),確保數(shù)據(jù)表空間和索引表空間置與不同的硬盤控制卡控制的硬盤上.” (全文完)Black_Snailligang1000@hotmail.com