ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 多层次子查询的sql执行顺序的问题

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

原创 Linux操作系统 作者:wj_zizi 时间:2011-05-16 16:36:06 0 删除 编辑
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/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2010-03-22

  • 博文量
    12
  • 访问量
    33055