Oracle語句優化規則彙總 4

2021-05-27 18:38:28 字數 3189 閱讀 6848

1. 使用表的別名(alias)

當在sql語句中連線多個表時, 請使用表的別名並把別名字首於每個column上。這樣一來,就可以減少解析的時間並減少那些由column歧義引起的語法錯誤。

(column歧義指的是由於sql中不同的表具有相同的column名,當sql語句中出現這個column時,sql解析器無法判斷這個column的歸屬)

2. 用exists替代in

在許多基於基礎表的查詢中,為了滿足乙個條件,往往需要對另乙個表進行聯接。在這種情況下, 使用exists(或not exists)通常將提高查詢的效率。

低效:select * 

from emp (基礎表) 

where empno > 0 

and deptno in (select deptno 

from dept 

where loc = 『melb』)

高效:select * 

from emp (基礎表) 

where empno > 0 

and exists (select 『x』 

from dept 

where dept.deptno = emp.deptno 

and loc = 『melb』)

(相對來說,用not exists替換not in 將更顯著地提高效率,下面將指出)

3. 用not exists替代not in

在子查詢中,not in子句將執行乙個內部的排序和合併。 無論在哪種情況下,not in都是最低效的 (因為它對子查詢中的表執行了乙個全表遍歷)。 為了避免使用not in ,我們可以把它改寫成外連線(outer joins)或not exists.

例如:select … 

from emp 

where dept_no not in (select dept_no 

from dept 

where dept_cat=』a』);

為了提高效率。改寫為:

(方法一: 高效)

select …. 

from emp a,dept b 

where a.dept_no = b.dept(+) 

and b.dept_no is null 

and b.dept_cat(+) = 『a』

(方法二: 最高效)

select …. 

from emp e 

where not exists (select 『x』 

from dept d 

where d.dept_no = e.dept_no 

and dept_cat = 『a』);

4. 用表連線替換exists

通常來說 , 採用表連線的方式比exists更有效率

select ename 

from emp e 

where exists (select 『x』 

from dept 

where dept_no = e.dept_no 

and dept_cat = 『a』);

(更高效)

select ename 

from dept d,emp e 

where e.dept_no = d.dept_no 

and dept_cat = 『a』 ;

(在rbo的情況下,前者的執行路徑包括filter,後者使用nested loop)

5. 用exists替換distinct

當提交乙個包含一對多表資訊(比如部門表和雇員表)的查詢時,避免在select子句中使用distinct. 一般可以考慮用exist替換

例如:低效:

select distinct dept_no,dept_name 

from dept d,emp e 

where d.dept_no = e.dept_no

高效:select dept_no,dept_name 

from dept d 

where exists ( select 『x』 

from emp e 

where e.dept_no = d.dept_no);

exists 使查詢更為迅速,因為rdbms核心模組將在子查詢的條件一旦滿足後,立刻返回結果。

6. 識別『低效執行』的sql語句

用下列sql工具找出低效sql:

select executions , disk_reads, buffer_gets, 

round((buffer_gets-disk_reads)/buffer_gets,2) hit_radio, 

round(disk_reads/executions,2) reads_per_run, 

sql_text 

from v$sqlarea 

where executions>0 

and buffer_gets > 0 

and (buffer_gets-disk_reads)/buffer_gets < 0.8 

order by 4 desc;

(雖然目前各種關於sql優化的圖形化工具層出不窮,但是寫出自己的sql工具來解決問題始終是乙個最好的方法)

7. 使用tkprof 工具來查詢sql效能狀態

sql trace 工具收集正在執行的sql的效能狀態資料並記錄到乙個跟蹤檔案中。 這個跟蹤檔案提供了許多有用的資訊,例如解析次數。執行次數,cpu使用時間等。這些資料將可以用來優化你的系統。

設定sql trace在會話級別:

有效  

alter session set sql_trace true

設定sql trace 在整個資料庫有效仿, 你必須將sql_trace引數在init.ora中設為true, user_dump_dest引數說明了生成跟蹤檔案的目錄

(這裡並沒有提到tkprof的用法, 對sql trace的用法也不夠準確, 設定sql trace首先要在init.ora中設定timed_statistics, 這樣才能得到那些重要的時間狀態。 生成的trace檔案是不可讀的,所以要用tkprof工具對其進行轉換,tkprof有許多執行引數。 大家可以參考oracle手冊來了解具體的配置。 )

Oracle語句優化規則彙總 4

1.使用表的別名 alias 當在sql語句中連線多個表時,請使用表的別名並把別名字首於每個column上。這樣一來,就可以減少解析的時間並減少那些由column歧義引起的語法錯誤。column歧義指的是由於sql中不同的表具有相同的column名,當sql語句中出現這個column時,sql解析器...

Oracle語句優化規則彙總 1

1.選用適合的oracle優化器 oracle的優化器共有3種 a.rule 基於規則 b.cost 基於成本 c.choose 選擇性 設定預設的優化器,可以通過對init.ora檔案中optimizer mode引數的各種宣告,如rule,cost,choose,all rows,first r...

Oracle語句優化規則彙總 2

1.where子句中的連線順序。oracle採用自下而上的順序解析where子句,根據這個原理,表之間的連線必須寫在其他where條件之前,那些可以過濾掉最大數量記錄的條件必須寫在where子句的末尾。例如 低效,執行時間156.3秒 select from emp e where sal 5000...