`

转-oracle 子查询

阅读更多

1 关联子查询与非关联子查询

 关联子查询需要在内部引用外部表,而非关联子查询不要引用外部表。对于父查询中处理的记录来说,一个关联子查询是每行计算一次,然而一个非关联子查询只会执行一次,而且结果集被保存在内存中(如果结果集比较小),或者放在一张oracle临时数据段中(如果结果集比较大)。一个“标量”子查询十一哥非关联子查询,返回唯一记录。如果子查询仅仅返回一个记录,那么oracle优化器会将结果缩减为一个常量,而且这个子查询只会执行一次。

2.如何选择?

  根据外部查询,以及子查询本身所返回的记录的数目。如果两种查询返回的结果是相同的,哪一个效率更好?

  关联子查询的系统开销:对于返回到外层查询的记录来说,子查询回每次执行一次。因此,必须保证任何可能的时候子查询都要使用索引。

  非关联子查询的系统开销:子查询只会执行一次,而且结果集通常是排好序的,并保存在临时数据段中,其中每一个记录在返回时都会被父级查询引用,在子查询返回大量记录的情况下,将这些结果集排序回增大系统的开销。

  所以:如果父查询只返回较少的记录,那么再次执行子查询的开销不会非常大,如果返回很多数据行,那么直查询就会执行很多次。 如果子查询返回较少的记录,那么为内存中保存父查询的结果集的系统开销不会非常大,如果子查询返回多行,那么需要将结果放在临时段上,然后对数据段排序,以便为负查询中的每个记录服务。

 

3结论:1)在使用一个关联子查询是,使用in 或者 exists子句的子查询执行计划通常都相同

       2)exists子句通常不适于子查询

       3)在外部查询返回相对较少记录时,关联子查询比非关联子查询执行得要更快。

       4)如果子查询中只有少量的记录,则非关联子查询会比关联子查询执行得更快。

4 子查询转化:子查询可以转化为标准连接操作

       1)使用in的非关联子查询(子查询唯一)

          条件:1)在整个层次结构中最底层数据表上定义唯一主键的数据列存在于子查询的select列表中

                2)至少有个定义了唯一主键的数据列在select列表中,而且定义唯一主键的其他数据列都必须有指定的相等标准,不管是直接指定,还是间接指定。

       2)使用exists子句的关联子查询

          条件:对于相关条件来说,该子查询只能返回一个记录。

 

5。not in和not exists调整

  1)not in 非关联子查询:转化为in写法下的minus子句

  2)not exists关联子查询:这种类型的反连接操作会为外部查询中每一个记录进行内部查询,除了不满足子查询中where条件的内部数据表以外,他会过滤掉所有记录。

    可以重写:在一个等值连接中指定外部链接条件,然后添加select distinct

    eg:select distinct ... from a,b where a.col1 = b.col1(+) and b.col1 is null

6。在子查询中使用all any

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics