Where子句中的連接順序
ORACLE采用自下而上的順序解析WHERE子句
根據這個原理 表之間的連接必須寫在其他WHERE條件之前 那些可以過濾掉最大數量記錄的條件必須寫在WHERE子句的末尾
舉例
(低效)select … from table t where t sal > and t jobtype = and < (select count(*) from table t where t pno = t tno;(高效)select … from table t where < (select count(*) from table t where t pno = t tno and t sal > and t jobtype = ; Select子句中避免使用 *
當妳想在select子句中列出所有的column時 使用動態SQL列引用 * 是壹個方便的方法
不幸的是 這是壹個非常低效的方法
實際上 ORACLE在解析的過程中 會將 * 依次轉換成所有的列名 這個工作是通過查詢數據字典完成的 這意味著將耗費更多的時間
減少訪問數據庫的次數
當執行每條SQL語句時 ORACLE在內部執行了許多工作
解析SQL語句 估算索引的利用率 綁定變量 讀數據塊等等
由此可見 減少訪問數據庫的次數 就能實際上減少ORACLE的工作量
舉例
題目——我要查找編號為 學生的信息
(低效)select name age gender address from t_student where id = ;select name age gender address from t_student where id = ;(高效)select a name a age a gender a address b name b age b gender b address from t_student a t_student b where a id = and b id = ; 使用Decode函數來減少處理時間
使用DECODE函數可以避免重復掃描相同記錄或重復連接相同的表
舉例
(低效)select count(*) sum(banace) from table where dept_id = and name like anger% ;select count(*) sum(banace) from table where dept_id = and name like anger% ;(高效)select? count(decode(dept_id XYZ null)) count_ count(decode(dept_id XYZ null)) count_ sum(decode(dept_id dept_id null)) sum_ sum(decode(dept_id dept_id null)) sum_ from table where name like anger% ; 整合簡單 無關聯的數據庫訪問
如果妳有幾個簡單的數據庫查詢語句 妳可以把它們整合到壹個查詢中(即使它們之間沒有關系)舉例
(低效)select name from table where id = ;select name from table where id = ;select name from table where id = ;(高效)select t name t name t namefrom table t table t table t where t id(+) = and t id(+) = and t id(+) =
註 上面例子雖然高效 但是可讀性差 需要量情而定啊![nextpage]
刪除重復記錄
最高效的刪除重復記錄方法 ( 因為使用了ROWID)舉例
delete from table t where t rowid > (select min(t rowid) from table t where t id = t id) 盡量不要使用having子句 可以考慮用where替換
having只會在檢索出所有記錄之後才對結果集進行過濾 這個處理需要排序 總計等操作
如果能通過where子句限制記錄的數目 那就能減少這方面的開銷 [nextpage]
盡量用表的別名
當在SQL語句中連接多個表時 請使用表的別名並把別名前綴於每個Column上
這樣壹來 就可以減少解析的時間並減少那些由Column歧義引起的語法錯誤
用exists替代in(發現好多程序員不知道這個怎麽用)
在許多基於基礎表的查詢中 為了滿足壹個條件 往往需要對另壹個表進行聯接
在這種情況下 使用exists(或not exists)通常將提高查詢的效率
舉例
(低效)select … from table t where t id > and pno in (select no from table where name like % ) (高效)select … from table t where t id > and exists (select from table t where t pno = t no and name like % ) 用not exists替代not in
在子查詢中 not in子句將執行壹個內部的排序和合並
無論在哪種情況下 not in都是最低效的 (因為它對子查詢中的表執行了壹個全表遍歷)
為了避免使用not in 我們可以把它改寫成外連接(Outer Joins)或not exists
用exists替換distinct
當提交壹個包含壹對多表信息的查詢時 避免在select子句中使用distinct 壹般可以考慮用exists替換舉例
(低效)select distinct d dept_no d dept_name from t_dept d t_emp e where d dept_no = e dept_no;(高效)select d dept_no d dept_name from t_dept d where exists (select from t_emp where d dept_no = e dept_no) exists使查詢更為迅速 因為RDBMS核心模塊將在子查詢的條件壹旦滿足後 立刻返回結果
用表連接替換exists
通常來說 采用表連接的方式比exists更有效率
舉例
(低效)select ename from emp e where exists (select from dept where dept_no = e dept_no and dept_cat = W ) SELECT ENAME(高效)select ename from dept d emp e where e dept_no = d dept_no and dept_cat = W ; 避免在索引列上使用is null和is not null避免在索引中使用任何可以為空的列 ORACLE將無法使用該索引
對於單列索引 如果列包含空值 索引中將不存在此記錄 對於復合索引 如果每個列都為空 索引中同樣不存在此記錄 如果至少有壹個列不為空 則記錄存在於索引中
舉例
如果唯壹性索引建立在表的A列和B列上 並且表中存在壹條記錄的A B值為( null) ORACLE將不接受下壹條具有相同A B值( null)的記錄(插入) 然而如果所有的索引列都為空 ORACLE將認為整個鍵值為空而空不等於空
因此妳可以插入 條具有相同鍵值的記錄 當然它們都是空!
lishixinzhi/Article/program/Oracle/201311/16701