IN和EXISTS
有時候會將一列和一系列值相比較。最簡單的辦法就是在where子句中使用子查詢。在where子句中可以使用兩種格式的子查詢。
第一種格式是使用IN操作符: ... where column in(select * from ... where ...);
第二種格式是使用EXIST操作符: ... where exists (select 'X' from ...where ...);
絕大多數人會使用第一種格式,因為它比較容易編寫,而實際上第二種格式要遠比第一種格式的效率高。在Oracle中可以將幾乎所有的IN操作符子查詢改寫為使用EXISTS的子查詢。
第二種格式中,子查詢以‘select 'X'’開始。運用EXISTS子句不管子查詢從表中抽取什麼數據它只查看where子句。這樣優化器就不必遍歷整個表而僅根據索引就可完成工作(這裡假定在where語句中使用的列存在索引)。相對於IN子句來說,EXISTS使用相連子查詢,構造起來要比IN子查詢困難一些。
通過使用EXISTS,Oracle系統會首先檢查主查詢,然後運行子查詢直到找到第一個匹配項,這就節省了時間。Oracle系統在執行IN子查詢時,首先執行子查詢,並將獲得的結果列表存放在一個加了索引的臨時表中。在執行子查詢之前,系統先將主查詢掛起,待子查詢執行完畢,存放在臨時表中以後再執行主查詢。這也就是使用EXISTS比使用IN通常查詢速度快的原因。
同時應盡可能使用NOT EXISTS來代替NOT IN,盡管二者都使用了NOT(不能使用索引而降低速度),但NOT EXISTS要比NOT IN查詢效率更高