Oracle中的in和exists区别二

select * from T1 where x in (select y from T2);

或者

select * from T1 where exists (select * from T2 where T2.y=T1.x); 

 

面对这样一条SQL语句,到底有多少种查询方法呢?前面已经说了我们最容易想到的两种查询方法,还有没其他方式?

 通过对大量inexists语句进行分析,发现oracle可能还会采用如下的查询方式。

一:先查子SQL,再把查询结果distinct,然后再查询主SQL

二:先查主SQL,然后对每一个结果去查询子SQL

三:先查询子SQL,根据查询结果然后查询主SQL,再distinct,这种方式相当于or扩展,即

Select distinct * from (

 select * from T1 where x=a  or select * from T1 where x=b  or select * from T1 where x=c……

) aa

四:先查询子SQL,然后将值进行hash散列,再查询主SQL,然后也将字段散列值进行对应,如果两个SQL散列值能对应上,即为查询结果,这种方式在关联字段两个表上面都没有索引时会经常采用。

上面四种基本上是oracle中常用来处理existsin的查询计划,在进行distinst的过程中还可以采取sort uniquehash unqiue等方式进行去重。

oracle基于成本的优化又分为first_rowsall_rows模式,first_rows即优先显示部分行数,all_rows全部数据最快显示,在这两种模式下,oracle选择的执行方式也会出现很大差异,再针对前面提到的四种查询方式分析,第一,三,四种查询方式都需要先对子表的数据进行全部处理,处理以后才能与主表的数据结合,而第二种方式先拿主表的一条数据,然后去子表匹配,所以如果是first_rows模式,则很快可以出现数据,但如果all_rows模式,则第二种方式也要查询出全部数据,这时和第一,三,四种查询方式的效率就可能相差不大,甚至经常会出现第四种方式能够更快的查询到全部的结果。当然具体会选择那种查询方式,oracle会根据成本分析来确定,这个里面的成本包括每个表的数据量,每个索引对应的记录数,索引对应的数据记录分布情况,索引块链接情况等等,所以如果表的分析数据不正确,查询效率就会完全不一样。

Oracle的成本分析是基于整个表的数据记录进行分析,但在我们的实际情况下,业务的不一样也往往会导致数据分布情况相差很大,如针对几个不同的类型,可能某个类型的数据很少,而另外某个类型的数据量很大,这样会造成查这两个类型的数据时性能会相差很大,虽然oracle提供了直方图等功能解决这些问题,但面对inexists这类语句,分析正确的难度会很大。更有甚着,因为我们的数据可能是由导入和录入等不同渠道来的,有可能某个类型的数据就全部是导入而来,这样这些数据基本上是分布在临近的某几块,这样对oracle的成本分析也会造成很大的不确定性。

总结:随着Oracle的发展,对SQL的处理方式不断改进,对我们写SQL的要求也越来越低,Oracle一般都能帮我们找到最好的执行方法,但如果我们要做SQL优化,就必须要对oracle的执行方式有彻底的了解,并且了解我们系统的业务数据分布情况,然后仔细分析可能的执行计划,才能得到最高效的SQL

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值