【正文】
拼一個春夏秋冬!贏一個無悔人生!早安!—————獻給所有努力的人.學(xué)習(xí)參考。不奮斗就是每天都很容易,可一年一年越來越難。是狼就要練好牙,是羊就要練好腿。CONNECT BY PRIOR ORG_NO = P_ORG_NO。使用嵌套查詢時,不必使用UNION ALL,改寫START WITH 即可,示例:SELECT ORG_NO FROM O START WITH ORG_NO = 39。UNION ALLSELECT ORG_NO FROM O WHERE ORG_NO = 39。如果至少有一個列不為空,則記錄存在于索引中如果唯一性索引建立在表的A列和B列上,并且表中存在一條記錄的A,B值為(123,null),Oracle將不接受下一條具有相同A,B值(123,null)的記錄插入如果所有的索引列都為空,Oracle將認為整個鍵值為空,而空不可能等于空,因此你可以插入1000條具有相同鍵值的記錄,當(dāng)然它們都是空!因為空值不存在于索引列中,所以WHERE子句中對索引列進行空值比較將使Oracle停用該索引低效(索引失效)SELECT … FROM DEPARTMENT WHERE DEPT_CODE IS NOT NULL規(guī)則15 使用UNIONALL和UNION當(dāng)SQL語句需要UNION兩個查詢結(jié)果集合時,這兩個結(jié)果集合會以UNIONALL的方式被合并,然后在輸出最終結(jié)果前進行排序如果用UNION ALL替代UNION,這樣排序就不是必要了,效率就會因此得到提高需要注意的是,UNION ALL將重復(fù)輸出兩個結(jié)果集合中相同記錄,因此還是要從業(yè)務(wù)需求分析使用UNION ALL的可行性關(guān)于索引下列經(jīng)驗請參考:1).如果檢索數(shù)據(jù)量超過30%的表中記錄數(shù),使用索引將沒有顯著的效率提高2).在特定情況下,使用索引也許會比全表掃描慢,但這是同一個數(shù)量級上的差距;而通常情況下,使用索引比全表掃描要快幾倍乃至幾千倍!規(guī)則16 嵌套查詢SELECT ORG_NO FROM OCONNECT BY PRIOR ORG_NO = P_ORG_NO START WITH P_ORG_NO = 39。請務(wù)必注意,檢索中不要對索引列進行處理,如:TRIM,TO_DATE,類型轉(zhuǎn)換等操作,破壞索引,使用全表掃描,影響SQL執(zhí)行效率。 示例:低效SELECT … FROM DEPT WHERE SAL * 12 25000。在這種情況下,Oracle將使用全表掃描規(guī)則13 避免在索引列上使用計算WHERE子句中,如果索引列是函數(shù)的一部分,優(yōu)化器將不使用索引而使用全表掃描。這個SQL的執(zhí)行分兩步,LODGING$MANAGER的索引范圍查詢(得到所有符合條件記錄的ROWID),通過ROWID訪問表得到LODGING列的值由于LODGING$MANAGER是一個非唯一性的索引,數(shù)據(jù)庫不能對它執(zhí)行索引唯一掃描WHERE子句中,如果索引列所對應(yīng)的值的第一個字符由通配符(WILDCARD)開始,索引將不被采用SELECT LODGING FROM LODGING WHERE MANAGER LIKE 39。 示例:SELECT LODGING FROM LODGING WHERE MANAGER = 39。M%39。在內(nèi)部,上述SQL將被分成兩步執(zhí)行:首先,LODGING_PK索引將通過索引唯一掃描的方式被訪問,獲得相對應(yīng)的ROWID;然后通過ROWID訪問表的方式執(zhí)行下一步檢索如果被檢索返回的列包括在INDEX列中,Oracle將不執(zhí)行第二步的處理(通過ROWID訪問表)因為檢索數(shù)據(jù)保存在索引中,單單訪問索引就可以完全滿足查詢結(jié)果 2).索引范圍查詢(INDEX RANGE SCAN) 適用于兩種情況: 1.基于唯一性索引的一個范圍的檢索 2.基于非唯一性索引的檢索216。Oracle對索引有兩種訪問模式:1).索引唯一掃描(INDEX UNIQUE SCAN)大多數(shù)情況下, 優(yōu)化器通過WHERE子句訪問INDEX例如:表LODGING有兩個索引:建立在LODGING列上的唯一性索引LODGING_PK和建立在MANAGER列上的非唯一性索引LODGING$MANAGERSELECT * FROM LODGING WHERE LODGING = 39。另一個使用索引的好處是,它提供了主鍵(primary key)的唯一性驗證除了那些LONG或LONG RAW數(shù)據(jù)類型,你可以索引幾乎所有的列通常在大型表中使用索引特別有效,當(dāng)然,在掃描小表時,使用索引同樣能提高效率,雖然使用索引能得到查詢效率的提高,但是我們也必須注意到它的代價,索引需要空間來存儲,也需要定期維護,每當(dāng)有記錄在表中增減或索引列被修改時,索引本身也會被修改。通常,通過索引查詢數(shù)據(jù)比全表掃描要快。規(guī)則12 用索引提高效率索引是表的一個概念部分,用來提高檢索數(shù)據(jù)的效率。 FROM EMP E WHERE = )。 示例:低效SELECT DISTINCT DEPT_NO, DEPT_NAME FROM DEPT D, EMP E WHERE = 高效SELECT DEPT_NO, DEPT_NAME FROM DEPT D WHERE EXISTS (SELECT 39。規(guī)則11 用EXISTS替換DISTINCT當(dāng)提交一個包含多表信息(比如部門表和雇員表)的查詢時,避免在SELECT子句中使用DISTINCT,一般可以考慮用EXIST替換。更高效SELECT ENAME FROM DEPT D, EMP E WHERE = AND DEPT_CAT = 39。A39。X39。216。)。 FROM DEPT D WHERE = AND DEPT_CAT = 39。最高效 SELECT … FROM EMP E WHERE NOT EXISTS (SELECT 39。為了提高效率改寫為高效SELECT … FROM EMP A, DEPT B WHERE = (+) AND IS NULL AND (+) = 39。A39。216。)。 FROM DEPT WHERE = AND LOC = 39。高效SELECT * FROM EMP(基礎(chǔ)表) WHERE EMPNO 0 AND EXISTS (SELECT 39。MELB39。216。別名使用字母必須為A、B、C、D…,必須順序使用。高效UPDATE EMP SET (EMP_CAT, SAL_RANGE) = (SELECT MAX(CATEGORY), MAX(SAL_RANGE) FROM EMP_CATEGORIES) WHERE EMP_DEPT = 0020。 GROUP BY REGION規(guī)則6 減少對表的查詢在含有子查詢的SQL語句中,要特別注意減少對表的查詢 216。 AND REGION != 39。高效SELECT REGION, AVG(LOG_SIZE) FROM LOCATION WHERE REGION REGION != 39。 AND REGION != 39。 示例:低效SELECT REGION, AVG(LOG_SIZE) FROM LOCATION GROUP BY REGION HAVING REGION REGION != 39。規(guī)則5 用Where子句替換HAVING子句避免使用HAVING子句,HAVING只會在檢索出所有記錄之后才對結(jié)果集進行過濾,這個處理需要排序、統(tǒng)計等操作,如果能通過WHERE子句限制記錄的數(shù)目,那就能減少這方面的開銷。X39。SMITH%39。002039。X39。003039。X39。002039。SMITH%39。003039。SMITH%39。002039。規(guī)則4 使用DECODE函數(shù)來減少處理時間使用DECODE函數(shù)可以避免重復(fù)掃描相同記錄或重復(fù)連接相同的表216?! ?END?! ?FETCH C1 INTO …,…,…?! ?FETCH C1 INTO …,…,…。方法2 (次低效)DECLARE CURSOR C1 (E_NO NUMBER) IS SELECT EMP_NAME,SALARY,GRADE FROM EMP WHERE EMP_NO = E_NO。 示例:以下有三種方法可以檢索出雇員號等于0342或0291的職員 方法1 (最低效)SELECT EMP_NAME, SALARY, GRADE FROM EMP WHERE EMP_NO = 342。依次轉(zhuǎn)換成所有的列名,這個工作是通過查詢數(shù)據(jù)字典完成的,這意味著將耗費更多的時間規(guī)則3 減少訪問數(shù)據(jù)庫的次數(shù)當(dāng)執(zhí)行每條SQL語句時,Oracle在內(nèi)部執(zhí)行了許多工作:解析SQL語句,估算索引的利用率,綁定變量,讀數(shù)據(jù)塊等等由此可見,減少訪問數(shù)據(jù)庫的次數(shù),就能實際上減少Oracle的工作量。實際上,Oracle在解析的過程中,會將39。*39。MANAGER39。 AND 25 (SELECT COUNT(*) FROM EMP WHERE MGR = )。 示例: (低效,) SELECT * FROM EMP E WHERE SAL 50000 AND JOB = 39。首先,掃描第一個表(FROM子句中最后的那個表)并對記錄進行排序;然后掃描第二個表(FROM子句中最后第二個表);最后將所有從第二個表中檢索出的記錄與第一個表中合適記錄進行合并例如: 表 TAB1 16,384 條記錄表 TAB2 5 條記錄,選擇TAB2作為基礎(chǔ)表 (最好的方法) select count(*) from tab1,tab2 ,選擇TAB2作為基礎(chǔ)表 (不佳的方法) select count(*) from tab2,tab1 ;如果有3個以上的表連接查詢,那就需要選擇交叉表(intersection table)作為基礎(chǔ)表,交叉表是指那個被其他表所引用的表 216。END MY_PROCEDURE。 RAISE_APPLICATION_ERROR(20001,v_error_info,TRUE)。 實現(xiàn)代碼 SQL Code EXCEPTION WHEN OT