SQL优化思考
发表于:2007-07-02来源:作者:点击数:
标签:
初入 oracle 殿堂的人,在学写 SQL 语句时一般会得到一个教诲,那就是exists比in更要高效,但仔细想象要是真的这么简单那干脆去掉in,岂不是省去很多麻烦? 自己对这两种查询语句写法的认识也比较浅显,但是觉得还是比较有效,所以有兴趣的可以瞄一眼哦 ...... 先
初入
oracle殿堂的人,在学写
SQL语句时一般会得到一个教诲,那就是exists比in更要高效,但仔细想象要是真的这么简单那干脆去掉in,岂不是省去很多麻烦?
自己对这两种查询语句写法的认识也比较浅显,但是觉得还是比较有效,所以有兴趣的可以瞄一眼哦
......
先说IN
他相当对inner table执行一个个带有distinct的子查询语句,然后得到的查询结果集再与outer table进行连接,当然连接的方式和索引的使用仍然同于普通的两表连接。
select * from T1 where x in (select y from T2);
可以转换成如下
select * from
T1,(select distinct y from T2) T2
where T1.x=T2.y;
再说exists
实际上exists相当于对outer table进行全表扫描,用从中检索到的每一行与inner table做循环匹配输出相应的符合条件的结果,其主要开销是对outer table的全表扫描(full scan),而连接方式是nested loop方式。
可以写成
select * from T1 where exists (select NULL from T2 where T2.y=T1.x);
转换成
for cursor1 in (select * from T1)
loop
if (exists (select NULL from T2 where T2.y=cursor1.x))
then
返回匹配的记录;
end if;
end loop;
通过上面的解释,现在很容易明白当T2数据量巨大且索引情况不好(大量重复值等),则不宜使用产生对T2的distinct检索而导致系统开支巨大的IN操作,反之当T1表数据量巨大(不受索引影响)而T2表数据较少且索引良好则不宜使用引起T1全表扫描的EXISTS操作,
原文转自:http://www.ltesting.net