20. 用表連接替換exists
通常來(lái)說(shuō) , 采用表連接的方式比exists更有效率
select ename
from emp e
where exists (select ‘x’
from dept
where dept_no = e.dept_no
and dept_cat = ‘a(chǎn)’);
(更高效)
select ename
from dept d,emp e
where e.dept_no = d.dept_no
and dept_cat = ‘a(chǎn)’ ;
(譯者按: 在rbo的情況下,前者的執(zhí)行路徑包括filter,后者使用nested loop)
21. 用exists替換distinct
當(dāng)提交一個(gè)包含一對(duì)多表信息(比如部門(mén)表和雇員表)的查詢(xún)時(shí),避免在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 使查詢(xún)更為迅速,因?yàn)閞dbms核心模塊將在子查詢(xún)的條件一旦滿(mǎn)足后,立刻返回結(jié)果.
22. 識(shí)別’低效執(zhí)行’的sql語(yǔ)句
用下列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;
(譯者按: 雖然目前各種關(guān)于sql優(yōu)化的圖形化工具層出不窮,但是寫(xiě)出自己的sql工具來(lái)解決問(wèn)題始終是一個(gè)最好的方法)
23. 使用tkprof 工具來(lái)查詢(xún)sql性能狀態(tài)
sql trace 工具收集正在執(zhí)行的sql的性能狀態(tài)數(shù)據(jù)并記錄到一個(gè)跟蹤文件中. 這個(gè)跟蹤文件提供了許多有用的信息,例如解析次數(shù).執(zhí)行次數(shù),cpu使用時(shí)間等.這些數(shù)據(jù)將可以用來(lái)優(yōu)化你的系統(tǒng).
設(shè)置sql trace在會(huì)話(huà)級(jí)別: 有效
alter session set sql_trace true
設(shè)置sql trace 在整個(gè)數(shù)據(jù)庫(kù)有效仿, 你必須將sql_trace參數(shù)在init.ora中設(shè)為true, user_dump_dest參數(shù)說(shuō)明了生成跟蹤文件的目錄
(譯者按: 這一節(jié)中,作者并沒(méi)有提到tkprof的用法, 對(duì)sql trace的用法也不夠準(zhǔn)確, 設(shè)置sql trace首先要在init.ora中設(shè)定timed_statistics, 這樣才能得到那些重要的時(shí)間狀態(tài). 生成的trace文件是不可讀的,所以要用tkprof工具對(duì)其進(jìn)行轉(zhuǎn)換,tkprof有許多執(zhí)行參數(shù). 大家可以參考o(jì)racle手冊(cè)來(lái)了解具體的配置. )