Oracle SQL語句優化

2021-09-02 05:02:26 字數 3922 閱讀 3648

1,建表時:

1)建立主鍵

2)建立索引

3)如果表資料量很大考慮建立分割槽

4)可以使用number型別的就不適用varchar2,這是因為引擎在處理查詢和連線時會逐個比較字串中每乙個字元,

而對於數字型而言只需要比較一次就夠了。

2,建立索引注意事項:

1)首先應考慮在 where 及 order by 涉及的列上建立索引。

2)避免在索引列上使用not

not會產生在和在索引列上使用函式相同的影響。當oracle遇到not,就會停止使用索引轉而執行全表掃瞄。

3)避免在索引列上使用計算

2,資料:

1)盡量不要儲存null,可以給預設值。避免where條件出現 is null 或 is not null。

3,寫sql語句時:

1)盡量避免在 where 子句中對字段進行 null 值判斷,否則將導致引擎放棄使用索引而進行全表掃瞄,

如:select id from t where num is null可以在num上設定預設值0,確保表中num列沒有null值,

然後這樣查詢:select id from t where num=0。

2)盡量避免在 where 子句中使用!=或<>操作符,否則將引擎放棄使用索引而進行全表掃瞄。

3)盡量避免在 where 子句中使用 or 來連線條件,否則將導致引擎放棄使用索引而進行全表掃瞄,

如:select id from t where num=10 or num=20

可以這樣查詢:select id from t where num=10union allselect id from t where num=20。

4)in 和 not in 也要慎用,否則會導致全表掃瞄。可以用exists替代。或者根據實際資料情況用其他函式代替。

如:select id from t where num in(1,2,3,4,5,6)

對於連續的數值,能用 between 就不要用 in 了:

select id from t where num between 1 and 6

5)where 條件後用like '%%' 也會導致全表掃瞄。

6)在 where 子句中使用引數,也會導致全表掃瞄。

因為sql只有在執行時才會解析區域性變數,但優化程式不能將訪問計畫的選擇推遲到執行時;它必須在編譯時進行選擇。然        而,如果在編譯時建立訪問計畫,變數的值還是未知的,因而無法作為索引選擇的輸入項。

如下面語句將進行全表掃瞄:

select id from t where num=v_num;

可以改為強制查詢使用索引:

select id from t with(index(索引名)) where num=v_num;  

7) 避免在 where 子句中對字段進行表示式操作,這將導致引擎放棄使用索引而進行全表掃瞄。如:

select id from t where num/2=100

應改為:

select id from t where num=100*2 ;

8) 盡量避免在where子句中對字段進行函式操作,這將導致引擎放棄使用索引而進行全表掃瞄。如:

select id from t where substring(name,1,3)='abc' ;

應改為:

select id from t where name like 'abc%';

9)不要在 where 子句中的「=」左邊進行函式、算術運算或其他表示式運算,否則系統將可能無法正確使用索引。

10)在使用索引字段作為條件時,如果該索引是復合索引,那麼必須使用到該索引中的第乙個字段作為條件時才能保證系統使用        該索引,否則該索引將不會被使用,並且應盡可能的讓字段順序與索引順序相一致。

11)盡量不要使用 select * from t ,用具體的字段列表代替「*」,不要返回用不到的任何字段。

12)在新建臨時表時,如果一次性插入資料量很大,那麼可以使用 select into 代替 create table,避免造成大量 log ,以提高速           度;如果資料量不大,為了緩和系統表的資源,應先create table,然後insert。

13)當對多個表進行連線查詢的時候,oracle分析器會按照從右到左的順序處理from字句中的表名

select a.emp_id,b.emp_deptid

from emp a.dept b;

在執行時,oracle會先查詢dept表,根據dept表查詢到行作為資料來源序列連線emp表繼續執行,因此dept表又稱為基礎表或者驅動 表。由於連線的順序對查詢的效率有非常大的影響,因此在處理多表連線時,必須選擇記錄條數較少的表作為基礎表。oracle會使用排序或者合併的方式進行連線,比如先掃瞄dept表,然後對dept表進行排序,再掃瞄emp表,最後將所有檢索出來的記錄與第乙個表的記錄進行合併。

如果有三個以上的表連線查詢,就需要選擇交叉表作為基礎表。交叉表是指那個被其他表所引用的表。由於emo_log是emp和dept表中的交叉表,既包含了dept表的內容又包含了emp的內容,因此上述查詢可以將emp_log作為驅動表

select a.emp_id,b.emp_deptid,c.emp_name

from  emp a.dept b,emp_log c;

14) 預設情況下,oracle採用自下而上的順序解析where字句,因此在處理多表查詢的時候,表之間的連線必須寫在其他的where       條件之前,但是過濾資料記錄的條件則必須寫在where子句的尾部,以便在過濾了資料之後再進行連線處理,這樣可以提公升         sql語句的效能。

select a.empno ,a.ename,c.deptno,b.sal

from emp b,dept c,emp_log a

where a.deptno=b.deptno

and c.deptno in (20,30);

15) 使用decode函式,靈活使用該函式可以減少很多對錶的不必要的訪問。

16)使用 >= 代替 >

因為dbms將直接跳到第乙個id等於4的記錄而後者將首先定位到id=3的記錄並且向前掃瞄到第乙個id大於3的記錄。

17)sql語句用大寫的,因為oracle總是先解析sql語句,把小寫的字母轉換成大寫的再執行。

18)盡量多使用commit

只要有可能,在程式中盡量多使用commit, 這樣程式的效能得到提高,需求也會因為commit所釋放的資源而減少:

commit所釋放的資源: 

a. 回滾段上用於恢復資料的資訊. 

b. 被程式語句獲得的鎖 

c. redo log buffer 中的空間 

d. oracle為管理上述3種資源中的內部花費

19)建立臨時表

1)會話級臨時表

會話級臨時表是指臨時表中的資料只在會話生命週期之中存在,當使用者退出會話結束的時候,oracle自動清除臨時表中資料。

格式:create global temporary table table_name    (   col1 type1,   col2 type2   ...  )   on commit preserve rows;  

2)事務級臨時表  事務級臨時表是指臨時表中的資料只在事務生命週期中存在。  

create global temporary table table_name    (    col1 type1,    col2 type2    ...  )   on commit delete rows; 

當乙個事務結束(commit or rollback),oracle自動清除臨時表中資料。 

20)undo 表空間

undo 表空間也很重要,如果你的邏輯裡面有大量的dml操作(delete,insert,update)這時會使用undo 表空間,

如果表空間太小會直接報錯(表空間不能擴充套件),即便不報錯程式能執行但是也會很慢,增大undo表空間後效率會有很大         的提公升。

Oracle SQL語句優化技術分析

操作符優化 in操作符 用in寫出來的sql的優點是比較容易寫及清晰易懂,這比較適合現代軟體開發的風格。但是用in的sql效能總是比較低的,從oracle執行的步驟來分析用in的sql與不用in的sql有以下區別 oracle 試圖將其轉換成多個表的連線,如果轉換不成功則先執行in裡面的子查詢,再查...

基於Oracle,SQL語句優化方法30例(01)

sql語句優化方法30例 在sql語句優化過程中,我們經常會用到hint,現總結一下在sql優化過程中常見oracle hint的用法 1.all rows 表明對語句塊選擇基於開銷的優化方法,並獲得最佳吞吐量,使資源消耗最小化.例如 select all rows emp no,emp nam,d...

Oracle SQL語句優化技術 解讀實戰技巧

在from後面的表中的列表順序會對sql執行效能影響,在沒有索引及oracle沒有對錶進行統計分析的情況下oracle會按表出現的順序進行鏈結。一.sql語言的使用 1.in 操作符 用in寫出來的sql的優點是比較容易寫及清晰易懂,這比較適合現代軟體開發的風格。但是用in的sql效能總是比較低的,...