• 多层次子查询的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/

  • 相关阅读:
    Go简介
    sRGB标准与伽马校正
    【Web】HTTP基本认证之 Basic Auth
    【ElasticSearch】 ElasticSearch SQL(十三)
    【ElasticSearch】 ElasticSearch X-Pack之用户认证(十二)
    【ElasticSearch】 ElasticSearch Java客户端(十一)
    【ElasticSearch】 ElasticSearch集群分布式文档(十)
    【ElasticSearch】 ElasticSearch集群之分片、副本、故障转移(九)
    【ElasticSearch】 ElasticSearch集群安装(八)
    【ElasticSearch】 全文搜索(七)
  • 原文地址:https://www.cnblogs.com/wl-blog/p/15189758.html
Copyright © 2020-2023  润新知