多层次子查询的sql执行顺序的问题

SQL里面嵌套子查询这是非常普遍的写法。
下面是有关子查询的一些说明:
子查询又称内部查询,而包含子查询的语句称之外部查询(又称主查询)。
所有的子查询可以分为两类,即相关子查询和非相关子查询。
非相关子查询是独立于外部查询的子查询,子查询总共执行一次,执行完毕后将值传递给外部查询。
相关子查询的执行依赖于外部查询的数据,外部查询执行一行,子查询就执行一次。
 
这个解释没问题,但是上周碰到个问题,2层子查询,其中相关子查询作为内层子查询,外层的是非相关的。这样的子查询到底算相关还是非相关呢?
 
 
select a.pro_name, a.pro_type, a.pro_price
  from supmka a, supmkb_1 b
 where a.pro_name = b.pro_name
   and a.pro_type = b.pro_type
   and a.pro_price = (select   d.pro_price
                        from (select distinct c.pro_price
                                from supmkb_2 c
                               where c.pro_no = b.pro_no) d
                       where rownum = 1);
 
红色标注的子查询是相关的(内层的表c和主查询的表b关联),而外层蓝色的是非相关的。
查看执行计划之后,发现优化器先做的红色部分的查询,然后再做蓝色,再做关联。也就是说,红色部分的c.pro_no = b.pro_no,优化器忽略了(版本是Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
这样的数据查出来肯定有问题。
 
如果把distinct的位置换一下,
select a.pro_name, a.pro_type, a.pro_price
  from supmka a, supmkb_1 b
 where a.pro_name = b.pro_name
   and a.pro_type = b.pro_type
   and a.pro_price = (select  distinct d.pro_price
                        from (select  c.pro_price
                                from supmkb_2 c
                               where c.pro_no = b.pro_no) d
                       where rownum = 1);
优化器会先做关联查询。把c.pro_no = b.pro_no条件带进去做查询了。
 
所以大家不要写这种关联嵌套非关联的子查询,优化器都不知道怎么处理了。
 
另外在做实验期间,还发现一个问题:
在Oracle Database 10g Enterprise Edition Release 10.2.0.3.0上执行
select a.pro_name, a.pro_type, a.pro_price
  from supmka a, supmkb_1 b
 where a.pro_name = b.pro_name
   and a.pro_type = b.pro_type
   and a.pro_price = (select   d.pro_price
                        from (select distinct c.pro_price
                                from supmkb_2 c
                               where c.pro_no = b.pro_no) d
                       where rownum = 1);
会报ora-00904,b.pro_no字段没有定义的错误。也就是说,优化器还是先执行了红色部分的SQL,但是并没有把where c.pro_no = b.pro_no条件忽略,导致了00904的错误。
而在10.2.0.1.0版本上,优化器直接忽略了where c.pro_no = b.pro_no条件。
 
实际上这个SQL写得非常不好。zizi只是抱着一种蛋疼的精神分析了一下SQL执行顺序,也算打发无聊的时间吧
 
 
 
 
 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/16591471/viewspace-695491/,如需转载,请注明出处,否则将追究法律责任。

 

转 http://blog.itpub.net/16591471/viewspace-695491/

原文地址:https://www.cnblogs.com/wl-blog/p/15189758.html