選擇一個好的表聯接順序(這是一個比較重要的原則)
當在WHERE子句中有多個表聯接時,WHERE子句中排在最後的表應當是返回行數可能最少的表,有過濾條件的子句應放在WHERE子句中的最後。
如:設從emp表查到的數據比較少或該表的過濾條件比較確定,能大大縮小查詢範圍,則將最具有選擇性部分放在WHERE子句中的最後:
select * from emp e,dept d where d.deptno >10 and e.deptno =30; 如果dept表返回的記錄數較多的話,上面的查詢語句會比下面的查詢語句響應快得多。
select * from emp e,dept d where e.deptno =30 and d.deptno >10;
●最好不要在WHERE子句中使用函數或表達式,如果要使用的話,最好統一使用相同的表達式或函數,這樣便於以後使用合理的索引。
SELECT * FROM T1 WHERE F1*2 = 100
改成
SELECT * FROM T1 WHERE F1 = 100/2
● 使用WHERE (NOT)EXISTS 來代替(NOT)IN子句,使用NOT EXISTS 子句可以有效地利用索引。
儘可能使用NOT EXISTS來代替NOT IN,儘管二者都使用了NOT(但NOT IN不能使用索引而降低速度),NOT EXISTS要比NOT IN查詢效率更高。
例子1:
SELECT dname, deptno FROM dept WHERE deptno NOT IN (SELECT deptno FROM emp);
例子2:
SELECT dname, deptno FROM dept WHERE NOT EXISTS (SELECT deptno FROM emp WHERE dept.deptno = emp.deptno);
明顯的,2要比1的執行性能好很多。
因爲1中對emp進行了全表掃描,這是很浪費時間的操作。而且1中沒有用到emp的索引, 因爲沒有where子句。而2中的語句對emp進行的是縮小範圍的查詢。
● 通過使用>=、<=等,避免使用NOT命令
如這個例子:
select * from employee where salary<>3000;
對這個查詢,可以改寫爲不使用NOT:
select * from employee where salary<3000 or salary>3000;
雖然這兩種查詢的結果一樣,但是第二種查詢方案會比第一種查詢方案更快些。第二種查詢允許Oracle對salary列使用索引,而第一種查詢則不能使用索引。
● 外部聯接 + 的用法
外部聯接+按其在=的左邊或右邊分左聯接和右聯接。若不帶+運算符的表中的一個行不直接匹配於帶+預算符的表中的任何行,則前者的行與後者中的一個空行相匹配並被返回。利用外部聯接+,可以替代效率十分低下的 not in 運算,大大提高運行速度。例如,下面這條命令執行起來很慢:
select a.empno from emp a where a.empno not in
(select empno from emp1 where job=‘SALE’);
索引倘若利用外部聯接,改寫命令如下:
select a.empno from emp a left join emp1 b
on a.empno=b.empno
where b.empno is null
and b.job=‘SALE’;
例如表少,但情況複雜的時候應該寫如下語句:
select a.empno AS empno,
(select emp2.address from emp2 where a.id=emp2.id) AS address,
(select emp3.address1 from emp3 where b.id=emp3.id) AS address1
from emp a left join emp1 b on a.empno=b.empno
where b.empno is null and b.job=‘SALE’
這樣運行速度明顯提高.
●在查詢時儘量少用格式轉換
如用 WHERE a.order_no = b.order_no
而不用
WHERE TO_NUMBER (substr(a.order_no, instr(b.order_no, ’.’)-1)
= TO_NUMBER (substr(a.order_no, instr(b.order_no, .’) - 1)
●Order by語句
索引ORDER BY語句決定了Oracle如何將返回的查詢結果排序。Order by語句對要排序的列沒有什麼特別的限制,也可以將函數加入列中(象聯接或者附加等)。任何在Order by語句的非索引項或者有計算表達式都將降低查詢速度。
仔細檢查order by語句以找出非索引項或者表達式,它們會降低性能。解決這個問題的辦法就是重寫order by語句以使用索引,也可以爲所使用的列建立另外一個索引,同時應絕對避免在order by子句中使用表達式。
如必須使用排序操作,請遵循如下規則: 如結果集不需唯一,使用union all代替union。
●IS NULL 與 IS NOT NULL
不能用null作索引,任何包含null值的列都將不會被包含在索引中。即使索引有多列這樣的情況下,只要這些列中有一列含有null,該列就會從索引中排除。也就是說如果某列存在空值,即使對該列建索引也不會提高性能。
任何在where子句中使用is null或is not null的語句優化器是不允許使用索引的。
●SELECT子句中避免使用 ‘ *‘
SELECT * FROM EMP
應改爲:
SELECT COLUMN FROM EMP
●當在SQL語句中連接多個表時, 最好使用表別名並把別名加在每個列上
●其他
使用count(*)而不要使用count(column_name)。
避免困難的正規表達式:LIKE通配符匹配,技術上叫正規表達式。但這種匹配特別耗費時間。例如:SELECT * FROM customer WHERE zipcode LIKE “98_ _ _”
即使在zipcode字段上建立了索引,也還是採用順序掃描的方式。如果把語句改爲
SELECT * FROM customer WHERE zipcode >98000
在執行查詢時就會利用索引來查詢,顯然會大大提高速度。
另外,以下語句也不會使用索引:
SELECT * FROM customer WHERE zipcode LIKE '[C-P]arsen'
SELECT * FROM customer WHERE zipcode LIKE 'parsen [^L]%'
SELECT * FROM customer WHERE zipcode LIKE '%parsen'