ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 子查询中的in与exists的区别

子查询中的in与exists的区别

原创 Linux操作系统 作者:dream_forever 时间:2008-08-31 21:53:06 0 删除 编辑

摘自:http://hi.baidu.com/epepj/blog/item/67bed611e24a19c7a6ef3f6e.html

子查询中的in与exists的区别

  在复杂的查询中,选择正确的子句将会对性能产生很大的影响。考虑一下在你的编码中使用过哪一些子句。

     在主要/明细关系表中写一个sql的时候,多数人都会经历这么一步,那就是决定是使用where exists(…)子句还是where值in(…)子句来编写查询语句。你可能会拒绝使用where exists,因为用它来编写的话,要返回一个值,在语法上很困难,而这正是你经常忽视的。

     可是,如果你使用基于规则的最优化的话,情况就会大不相同了。你可以通过了解哪个表是驱动表,以及每一部份会返回多少行,来确定一个基于规则的查询的性能。

    当你用in子句来写一个查询语句的时候,就等于你向该基于规则的最优化传达了这样一个信息,即你想让内部的查询推动外部的查询(假定:in=由里而外)。举例来说,为在一个有14行记录的emp表中查询员工名称等于“king”的所有记录到一个直接报表中,你可以这样写:

    select ename from emp e

        where mgr in (select empno from emp where ename = king);

    以下是关于这个查询的说明计划:

    object     operation

    ---------- ----------------------------------------

                 select statement()

                  nested loops()

    emp                table access(full)

    emp                 table access(by index rowid)

    pk_emp               index(unique scan)

    这个查询实际上等同于以下这个:

    select e1.ename from emp e1,(select empno from emp where ename = king) e2  where e1.mgr = e2.empno;

    你可以用exists写同样的查询,你只要把外部查询一栏移到一个像下面这样的子查询环境中就可以了:

    select ename from emp e

        where exists (select 0 from emp where e.mgr = empno and ename = king);

    当你在一个where子句中写exists时,又等于向最优化传达了这样一条信息,即你想让外部查询先运行,使用每一个值来从内部查询(假定:exists=由外而内)中得到一个值。

    关于这个查询的说明计划如下:

    object     operation

    ---------- ----------------------------------------

                 select statement()

                  filter()

    emp                table access(full)

    emp                 table access(by index rowid)

    pk_emp               index(unique scan)

    这实际上与pl/sql编码类似:

    set serveroutput on;

    declare

        l_count integer;

    begin

        for e in (select mgr,ename from emp) loop

            select count(*) into l_count from emp

             where e.mgr = empno and ename = king;

            if l_count != 0 then

                dbms_output.put_line(e.ename);

            end if;

        end loop;

    end;

    为了确定在基于规则的最优化中,哪一种子句性能更佳,不妨考虑一下,与外部查询相比,内部查询会返回多少行记录。许多情况下,exists的表现更突出,这是因为,它需要你指定一个加入条件,这就可以调用一个index扫描。尽管如此,如果该查询的结果很小的话,in常常表现得更好。你通常都愿意运行那些能首先返回较少的结果的查询。

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

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

注册时间:2008-04-01

  • 博文量
    23
  • 访问量
    25327