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...