一、儘可能少用IN操做符
基本上全部的IN操做符均可以用EXISTS代替,在選擇IN或EXIST操做時,要根據主子表數據量大小來具體考慮
二、儘可能用NOT EXISTS或者外鏈接替代NOT IN操做符
由於NOT IN不能應用表的索引
三、儘可能不用「<>」或者「!=」操做符
不等於操做符是永遠不會用到索引的,所以對它的處理只會產生全表掃描。好比:a<>0 改成 a>0 or a<0
四、在設計表時,把索引列設置爲NOT NULL
判斷字段是否爲空通常是不會應用索引的,由於B樹索引是不索引空值的。
五、儘可能不用通配符「%」或者「_」做爲查詢字符串的第一個字符
當通配符「%」或者「_」做爲查詢字符串的第一個字符時,索引不會被使用。好比用T表中Column1 LIKE ?%5400%? 這個條件會產生全表掃描,若是改爲Column1 ?X5400%? OR Column1 LIKE ?B5400%? 則會利用Column1的索引進行兩個範圍的查詢,性能確定大大提升。
六、Where子句中避免在索引列上使用計算
若是索引不是基於函數的,那麼當在Where子句中對索引列使用函數時,索引再也不起做用。所以Where子句中避免在索引列上使用計算。
好比: substr(no,1,4)=?5400?,優化處理:no like ?5400%? trunc(hiredate)=trunc(sysdate),優化處理:hiredate >=trunc(sysdate) and hiredate <trunc(sysdate+1)
七、用「>=」替代「>」
大於或小於操做符通常狀況下是不用調整的,由於它有索引就會採用索引查找,但有的狀況下能夠對它進行優化,如一個表有100萬記錄,一個數值型字段A, 30萬記錄的A=0,30萬記錄的A=1,39萬記錄的A=2,1萬記錄的A=3。那麼執行A>2與A>=3的效果就有很大的區別了,由於 A>2時ORACLE會先找出爲2的記錄索引再進行比較,而A>=3時ORACLE則直接找到=3的記錄索引.
八、利用SGA共享池,避開parse階段
同一功能同一性能不一樣寫法SQL的影響 如一個SQL在
A程序員寫的爲 Select * from zl_yhjbqk
B程序員寫的爲 Select * from dlyx.zl_yhjbqk(帶表全部者的前綴)
C程序員寫的爲 Select * from DLYX.ZLYHJBQK(大寫表名)
D程序員寫的爲 Select * from DLYX.ZLYHJBQK(中間多了空格)
以上四個SQL在ORACLE分析整理以後產生的結果及執行的時間是同樣的,可是從ORACLE共享內存SGA的原理,能夠得出ORACLE對每一個SQL 都會對其進行一次分析,而且佔用共享內存,若是將SQL的字符串及格式寫得徹底相同則ORACLE只會分析一次,共享內存也只會留下一次的分析結果,這不只能夠減小分析SQL的時間,並且能夠減小共享內存重複的信息,ORACLE也能夠準確統計SQL的執行頻率。
九、WHERE後面的條件順序要求
WHERE後面的條件,錶鏈接語句寫在最前,能夠過濾掉最大數量記錄的條件居後。
好比: Select * from zl_yhjbqk where dy_dj = '1KV如下' and xh_bz=1 Select * from zl_yhjbqk where xh_bz=1 and dy_dj = '1KV如下' 以上兩個SQL中dy_dj(電壓等級)及xh_bz(銷戶標誌)兩個字段都沒進行索引,因此執行的時候都是全表掃描,第一條SQL的dy_dj = '1KV如下'條件在記錄集內比率爲99%,而xh_bz=1的比率只爲0.5%,在進行第一條SQL的時候99%條記錄都進行dy_dj及xh_bz
十、使用表的別名,並將之做爲每列的前綴
當在Sql語句中鏈接多個表時,使用表的別名,並將之做爲每列的前綴。這樣能夠減小解析時間
十一、進行了顯式或隱式的運算的字段不能進行索引
好比: ss_df+20>50,優化處理:ss_df>30 ?X?||hbs_bh>?X5400021452?,優化處理:hbs_bh>?5400021542? sk_rq+5=sysdate,優化處理:sk_rq=sysdate-5 hbs_bh=5401002554,優化處理:hbs_bh=? 5401002554?,注:此條件對hbs_bh 進行隱式的to_number轉換,由於hbs_bh字段是字符型。
十二、用UNION ALL代替UNION
UNION是最經常使用的集操做,使多個記錄集聯結成爲單個集,對返回的數據行有惟一性要求,因此oracle就須要進行SORT UNIQUE操做(與使用distinct時操做相似),若是結果集又比較大,則操做會比較慢; UNION ALL操做不排除重複記錄行,因此會快不少,若是數據自己重複行存在可能性較小時,用union all會比用union效率高不少!
1三、其餘操做
儘可能使用packages: Packages在第一次調用時能將整個包load進內存,對提升性能有幫助。
儘可能使用cached sequences 來生成primary key :提升主鍵生成速度和使用性能。
很好地利用空間:如用VARCHAR2 數據類型代替CHAR等
1四、經過改變oracle的SGA的大小
SGA:數據庫的系統全局區。
SGA主要由三部分構成:共享池、數據緩衝區、日誌緩衝區
一、 共享池又由兩部分構成:共享SQL區和數據字典緩衝區。共享SQL區專門存放用戶SQL命令,oracle使用最近最少使用等優先級算法來更新覆蓋;數據字典緩衝區(library cache)存放數據庫運行的動態信息。數據庫運行一段時間後,DBA須要查看這些內存區域的命中率以從數據庫角度對數據庫性能調優。經過執行下述語句查看: select (sum(pins - reloads)) / sum(pins) "Lib Cache" from v$librarycache; --查看共享SQL區的重用率,最好在90%以上,不然須要增長共享池的大小。 select (sum(gets - getmisses - usage - fixED)) / sum(gets) "Row Cache" from v$rowcache; --查看數據字典緩衝區的命中率,最好在90%以上,不然須要增長共享池的大小。 二、 數據緩衝區:存放sql運行結果抓取到的data block; SELECT name, value FROM v$sysstat WHERE name IN ('db block gets', 'consistent gets','physical reads'); --查看數據庫數據緩衝區的使用狀況。查詢出來的結果能夠計算出來數據緩衝區的使用命中率=1 - ( physical reads / (db block gets + consistent gets) )。命中率應該在90%以上,不然須要增長數據緩衝區的大小。 三、 日誌緩衝區:存放數據庫運行生成的日誌。 select name,value from v$sysstat where name in ('redo entries','redo log space requests'); --查看日誌緩衝區的使用狀況。查詢出的結果能夠計算出日誌緩衝區的申請失敗率:申請失敗率=requests/entries,申請失敗率應該接近於0,不然說明日誌緩衝區開設過小,須要增長ORACLE數據庫的日誌緩衝區。
使用Sql優化工具:sqlexpert;toad;explain-table;PL/SQL;OEM