Vincent.Chan‘s Blog

          導(dǎo)航

          <2025年6月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

          公告

          本博客僅為收集留待閱讀。在此對原作者表示感謝。
          ---------------------------

          留言簿(11)

          隨筆分類

          文章分類

          隨筆檔案

          文章檔案

          相冊

          閱讀排行榜

          評論排行榜

          常用鏈接

          統(tǒng)計

          積分與排名

          網(wǎng)站

          最新評論

          ORACLE SQL性能優(yōu)化系列 (十三)

          ORACLE SQL性能優(yōu)化系列 (十三)

          作者: black_snail

           

          關(guān)鍵字 ORACLE PERFORMANCE TUNING PL/SQL

          出處 http://www.dbasupport.com



          43. 用WHERE替代ORDER BY

          ORDER BY 子句只在兩種嚴(yán)格的條件下使用索引.


          ORDER BY中所有的列必須包含在相同的索引中并保持在索引中的排列順序.

          ORDER BY中所有的列必須定義為非空.


          WHERE子句使用的索引和ORDER BY子句中所使用的索引不能并列.


          例如:

          表DEPT包含以下列:

          DEPT_CODE PK NOT NULL

          DEPT_DESC NOT NULL

          DEPT_TYPE NULL


          非唯一性的索引(DEPT_TYPE)


          低效: (索引不被使用)

          SELECT DEPT_CODE

          FROM DEPT

          ORDER BY DEPT_TYPE


          EXPLAIN PLAN:

          SORT ORDER BY

          TABLE ACCESS FULL


          高效: (使用索引)


          SELECT DEPT_CODE

          FROM DEPT

          WHERE DEPT_TYPE > 0


          EXPLAIN PLAN:

          TABLE ACCESS BY ROWID ON EMP

          INDEX RANGE SCAN ON DEPT_IDX

          譯者按:

          ORDER BY 也能使用索引! 這的確是個容易被忽視的知識點. 我們來驗證一下:

          SQL> select * from emp order by empno;

          Execution Plan

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

          0 SELECT STATEMENT Optimizer=CHOOSE

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

          2 1 INDEX (FULL SCAN) OF 'EMPNO' (UNIQUE)



          44. 避免改變索引列的類型.

          當(dāng)比較不同數(shù)據(jù)類型的數(shù)據(jù)時, ORACLE自動對列進(jìn)行簡單的類型轉(zhuǎn)換.


          假設(shè) EMPNO是一個數(shù)值類型的索引列.


          SELECT …

          FROM EMP

          WHERE EMPNO = ‘123'


          實際上,經(jīng)過ORACLE類型轉(zhuǎn)換, 語句轉(zhuǎn)化為:

          SELECT …

          FROM EMP

          WHERE EMPNO = TO_NUMBER(‘123')


          幸運的是,類型轉(zhuǎn)換沒有發(fā)生在索引列上,索引的用途沒有被改變.


          現(xiàn)在,假設(shè)EMP_TYPE是一個字符類型的索引列.

          SELECT …

          FROM EMP

          WHERE EMP_TYPE = 123


          這個語句被ORACLE轉(zhuǎn)換為:

          SELECT …

          FROM EMP

          WHERE TO_NUMBER(EMP_TYPE)=123


          因為內(nèi)部發(fā)生的類型轉(zhuǎn)換, 這個索引將不會被用到!

          譯者按:

          為了避免ORACLE對你的SQL進(jìn)行隱式的類型轉(zhuǎn)換, 最好把類型轉(zhuǎn)換用顯式表現(xiàn)出來. 注意當(dāng)字符和數(shù)值比較時, ORACLE會優(yōu)先轉(zhuǎn)換數(shù)值類型到字符類型.



          45. 需要當(dāng)心的WHERE子句

          某些SELECT 語句中的WHERE子句不使用索引. 這里有一些例子.

          在下面的例子里, ‘!=' 將不使用索引. 記住, 索引只能告訴你什么存在于表中, 而不能告訴你什么不存在于表中.

          不使用索引:

          SELECT ACCOUNT_NAME

          FROM TRANSACTION

          WHERE AMOUNT !=0;

          使用索引:

          SELECT ACCOUNT_NAME

          FROM TRANSACTION

          WHERE AMOUNT >0;


          下面的例子中, ‘||'是字符連接函數(shù). 就象其他函數(shù)那樣, 停用了索引.

          不使用索引:

          SELECT ACCOUNT_NAME,AMOUNT

          FROM TRANSACTION

          WHERE ACCOUNT_NAME||ACCOUNT_TYPE='AMEXA';

          使用索引:

          SELECT ACCOUNT_NAME,AMOUNT

          FROM TRANSACTION

          WHERE ACCOUNT_NAME = ‘AMEX'

          AND ACCOUNT_TYPE=' A';


          下面的例子中, ‘+'是數(shù)學(xué)函數(shù). 就象其他數(shù)學(xué)函數(shù)那樣, 停用了索引.

          不使用索引:

          SELECT ACCOUNT_NAME, AMOUNT

          FROM TRANSACTION

          WHERE AMOUNT + 3000 >5000;

          使用索引:

          SELECT ACCOUNT_NAME, AMOUNT

          FROM TRANSACTION

          WHERE AMOUNT > 2000 ;

          下面的例子中,相同的索引列不能互相比較,這將會啟用全表掃描.

          不使用索引:

          SELECT ACCOUNT_NAME, AMOUNT

          FROM TRANSACTION

          WHERE ACCOUNT_NAME = NVL(:ACC_NAME,ACCOUNT_NAME);

          使用索引:

          SELECT ACCOUNT_NAME, AMOUNT

          FROM TRANSACTION

          WHERE ACCOUNT_NAME LIKE NVL(:ACC_NAME,'%');


          譯者按:

          如果一定要對使用函數(shù)的列啟用索引, ORACLE新的功能: 基于函數(shù)的索引(Function-Based Index) 也許是一個較好的方案.

          CREATE INDEX EMP_I ON EMP (UPPER(ename)); /*建立基于函數(shù)的索引*/

          SELECT * FROM emp WHERE UPPER(ename) = ‘BLACKSNAIL'; /*將使用索引*/

          posted on 2006-02-25 22:34 Vincent.Chen 閱讀(189) 評論(0)  編輯  收藏 所屬分類: Database

          主站蜘蛛池模板: 长宁县| 东港市| 汾西县| 华亭县| 舟曲县| 宜章县| 利津县| 军事| 定陶县| 芷江| 南雄市| 新和县| 凤城市| 巴塘县| 石景山区| 福安市| 蒲江县| 会理县| 会宁县| 陵川县| 新民市| 杭锦旗| 平湖市| 饶阳县| 镇坪县| 勐海县| 新兴县| 黑河市| 女性| 德阳市| 兴和县| 梁河县| 淳安县| 九寨沟县| 温州市| 罗甸县| 赤城县| 崇州市| 法库县| 西丰县| 邵阳市|