知识大全 oracle in和exists、not in和not exists原理和性能探究

Posted

篇首语:风流不在谈锋胜,袖手无言味最长。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 oracle in和exists、not in和not exists原理和性能探究相关的知识,希望对你有一定的参考价值。

  对于in和exists not in和not exists还是有很多的人有疑惑 更有甚者禁用not in 所有的地方都要用not exists 它真的高效吗?通过下面的使用我们来证明

  先制造一些数据

  SQL> drop table test purge;

  SQL> drop table test purge;

  SQL> create table test as select * from dba_objects where rownum <= ;

  SQL> create table test as select * from dba_objects;

  SQL> exec dbms_stats gather_table_stats(user test )

  SQL> exec dbms_stats gather_table_stats(user test )

  SQL> set autotrace traceonly

  in和exists原理及性能实验

  SQL> select * from test t where t object_id in (select t object_id from test t )

  已选择 行

  执行计划

  

  Plan hash value:

  

  | Id  | Operation          | Name  | Rows  | Bytes | Cost (%CPU)| Time     |

  

  |   | SELECT STATEMENT   |       |   | |      ( )| : : |

  |*  |  HASH JOIN SEMI    |       |   | |      ( )| : : |

  |   |   TABLE ACCESS FULL| TEST |  | |        ( )| : : |

  |   |   TABLE ACCESS FULL| TEST | |   K|      ( )| : : |

  

  Predicate Information (identified by operation id)

  

   access( T OBJECT_ID = T OBJECT_ID )

  统计信息

  

     recursive calls

     db block gets

     consistent gets

     physical reads

     redo size

     bytes sent via SQL*Net to client

     bytes received via SQL*Net from client

     SQL*Net roundtrips to/from client

     sorts (memory)

     sorts (disk)

     rows processed

  SQL> select *  from test t

      where exists (select from test t where t object_id = t object_id)

  已选择 行

  执行计划

  

  Plan hash value:

  

  | Id  | Operation          | Name  | Rows  | Bytes | Cost (%CPU)| Time     |

  

  |   | SELECT STATEMENT   |       |   | |      ( )| : : |

  |*  |  HASH JOIN SEMI    |       |   | |      ( )| : : |

  |   |   TABLE ACCESS FULL| TEST |  | |        ( )| : : |

  |   |   TABLE ACCESS FULL| TEST | |   K|      ( )| : : |

  

  Predicate Information (identified by operation id)

  

   access( T OBJECT_ID = T OBJECT_ID )

  统计信息

  

     recursive calls

     db block gets

     consistent gets

     physical reads

     redo size

     bytes sent via SQL*Net to client

     bytes received via SQL*Net from client

     SQL*Net roundtrips to/from client

     sorts (memory)

     sorts (disk)

     rows processed

  结论 在oracle g中 in 和 exists其实是一样的 原理就是两张表做HASH JOIN SEMI 也可以通过 事件看到两条sql语句最终转换成同一条sql

  not in和not exists原理及性能实验

  not exists 比 not in效率高的例子

  SQL> select count(*) from test where object_id not in(select object_id from test )

  执行计划

  

  Plan hash value:

  

  | Id  | Operation           | Name  | Rows  | Bytes | Cost (%CPU)| Time     |

  

  |   | SELECT STATEMENT    |       |     |     |    ( )| : : |

  |   |  SORT AGGREGATE     |       |     |     |            |          |

  |*  |   FILTER            |       |       |       |            |          |

  |   |    TABLE ACCESS FULL| TEST |  |  |        ( )| : : |

  |*  |    TABLE ACCESS FULL| TEST |     |     |      ( )| : : |

  

  Predicate Information (identified by operation id)

  

   filter( NOT EXISTS (SELECT /*+ */ FROM TEST TEST WHERE

  LNNVL( OBJECT_ID <>:B )))

   filter(LNNVL( OBJECT_ID <>:B ))

  统计信息

  

     recursive calls

     db block gets

     consistent gets

     physical reads

     redo size

     bytes sent via SQL*Net to client

     bytes received via SQL*Net from client

     SQL*Net roundtrips to/from client

     sorts (memory)

     sorts (disk)

     rows processed

  SQL> select count(*) from test t where not exists

  (select from test t where t object_id=t object_id)

  执行计划

  

  Plan hash value:

  

  | Id  | Operation           | Name  | Rows  | Bytes | Cost (%CPU)| Time     |

  

  |   | SELECT STATEMENT    |       |     |     |      ( )| : : |

  |   |  SORT AGGREGATE     |       |     |     |            |          |

  |*  |   HASH JOIN ANTI    |       |     |    |      ( )| : : |

  |   |    TABLE ACCESS FULL| TEST |  |  |        ( )| : : |

  |   |    TABLE ACCESS FULL| TEST | |   K|      ( )| : : |

  

  Predicate Information (identified by operation id)

  

   access( T OBJECT_ID = T OBJECT_ID )

  统计信息

  

     recursive calls

     db block gets

     consistent gets

     physical reads

     redo size

     bytes sent via SQL*Net to client

     bytes received via SQL*Net from client

     SQL*Net roundtrips to/from client

     sorts (memory)

     sorts (disk)

     rows processed

  not in比not exists 效率高的例子

  SQL> Set autotrace off

  SQL> drop table test purge;

  表已删除

  SQL> drop table test purge;

  表已删除

  SQL> create table test as select * from dba_objects where rownum <= ;

  表已创建

  SQL> create table test as select * from dba_objects;

  表已创建

  SQL> Insert into test select * from dba_objects;

  已创建 行

  SQL> Insert into test select * from test ;

  已创建 行

  SQL> Insert into test select * from test ;

  已创建 行

  SQL> Commit;

  提交完成

  SQL> exec dbms_stats gather_table_stats(user test )

  PL/SQL 过程已成功完成

  SQL> exec dbms_stats gather_table_stats(user test )

  PL/SQL 过程已成功完成

  SQL> Set autotrace traceonly

  SQL> select count(*) from test where object_id not in(select object_id from test )

  执行计划

  

  Plan hash value:

  

  | Id  | Operation           | Name  | Rows  | Bytes | Cost (%CPU)| Time     |

  

  |   | SELECT STATEMENT    |       |     |     |     ( )| : : |

  |   |  SORT AGGREGATE     |       |     |     |            |          |

  |*  |   FILTER            |       |       |       |            |          |

  |   |    TABLE ACCESS FULL| TEST |     |    |        ( )| : : |

  |*  |    TABLE ACCESS FULL| TEST |     |    |     ( )| : : |

  

  Predicate Information (identified by operation id)

  

   filter( NOT EXISTS (SELECT /*+ */ FROM TEST TEST WHERE

  LNNVL( OBJECT_ID <>:B )))

   filter(LNNVL( OBJECT_ID <>:B ))

  统计信息

  

     recursive calls

     db block gets

     consistent gets

     physical reads

     redo size

     bytes sent via SQL*Net to client

     bytes received via SQL*Net from client

     SQL*Net roundtrips to/from client

     sorts (memory)

     sorts (disk)

     rows processed

  SQL> select count(*) from test t where not exists

  (select from test t where t object_id=t object_id)

  执行计划

  

  Plan hash value:

  

  | Id  | Operation           | Name  | Rows  | Bytes | Cost (%CPU)| Time     |

  

  |   | SELECT STATEMENT    |       |     |     |     ( )| : : |

  |   |  SORT AGGREGATE     |       |     |     |            |          |

  |*  |   HASH JOIN ANTI    |       |     |     |     ( )| : : |

  |   |    TABLE ACCESS FULL| TEST |     |    |        ( )| : : |

  |   |    TABLE ACCESS FULL| TEST |   K|  K|     ( )| : : |

  

  Predicate Information (identified by operation id)

  

   access( T OBJECT_ID = T OBJECT_ID )

  统计信息

  

     recursive calls

     db block gets

     consistent gets

     physical reads

     redo size

     bytes sent via SQL*Net to client

     bytes received via SQL*Net from client

     SQL*Net roundtrips to/from client

     sorts (memory)

     sorts (disk)

     rows processed

  结论 not in 和not exists原理是nestedloops 与HASH JOIN的区别 not in中的filter算法类似于nestedloops 如果比较两者的性能 就是比较nestedloops 与HASH JOIN的性能差异 在本例子中

  not in 性能 大于not exists  test 的数据量 条 test 数量 多万条

cha138/Article/program/Oracle/201311/17657

相关参考