查看: 8599|回复: 59

请教in和exists的区别

[复制链接]
论坛徽章:
76
双子座
日期:2015-07-28 14:26:072012新春纪念徽章
日期:2012-02-13 15:09:52ITPUB十周年纪念徽章
日期:2011-11-01 16:21:15鲜花蛋
日期:2011-08-26 02:02:24管理团队成员
日期:2011-05-07 01:45:082010广州亚运会纪念徽章:皮划艇
日期:2011-04-18 11:24:412011新春纪念徽章
日期:2011-02-18 11:43:342011新春纪念徽章
日期:2011-01-25 15:42:562011新春纪念徽章
日期:2011-01-25 15:42:332011新春纪念徽章
日期:2011-01-25 15:42:15
跳转到指定楼层
1#
发表于 2008-4-14 11:05 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
表的分布情况 采用cbo 数据和索引都已分析 ,麻烦讲下这in和exists两种方式的区别,为什么相差这么大?
tb_role 为8960行  建有parent_id的索引
tb_user 为8541行 建有role_id的索引
SQL> select id, role_id, login
  2 from tb_user e
  3 where Exists (Select ID
  4 From tb_role f
  5 where e.role_id = f.id
  6 Connect By Prior Id = parent_id
  7 Start With Id = 1);

8369 rows selected.


Execution Plan
----------------------------------------------------------
   0 SELECT STATEMENT Optimizer=CHOOSE (Cost=1292 Card=428 Bytes=
          9416)

   1 0 FILTER
   2 1 TABLE ACCESS (FULL) OF 'tb_user' (Cost=8 Card=428 Byte
          s=9416)

   3 1 FILTER
   4 3 CONNECT BY (WITH FILTERING)
   5 4 NESTED LOOPS
   6 5 INDEX (UNIQUE SCAN) OF 'PK_tb_role' (UNIQUE)
           (Cost=1 Card=1 Bytes=5)

   7 5 TABLE ACCESS (BY USER ROWID) OF 'tb_role'
   8 4 NESTED LOOPS
   9 8 BUFFER (SORT)
  10 9 CONNECT BY PUMP
  11 8 TABLE ACCESS (BY INDEX ROWID) OF 'tb_role' (
          Cost=3 Card=18 Bytes=162)

  12 11 INDEX (RANGE SCAN) OF 'INX_tb_role_PARENT_
          ID' (NON-UNIQUE) (Cost=1 Card=18)





Statistics
----------------------------------------------------------
          0 recursive calls
          0 db block gets
   84313553 consistent gets
          0 physical reads
          0 redo size
     224163 bytes sent via SQL*Net to client
       6553 bytes received via SQL*Net from client
        559 SQL*Net roundtrips to/from client
     142392 sorts (memory)
          0 sorts (disk)
       8369 rows processed

SQL>
一致性读达到 84313553 consistent gets ,而造成数据很慢查出来

改用in的方式 一致性读马上降低到10250  ,马上查出数据
SQL> select id, role_id, login
  2 from tb_user e
  3 where role_id in (Select ID
  4 From tb_role f
  5 Connect By Prior Id = parent_id
  6 Start With Id = 1);

8369 rows selected.


Execution Plan
----------------------------------------------------------
   0 SELECT STATEMENT Optimizer=CHOOSE (Cost=14 Card=18 Bytes=630
          )

   1 0 HASH JOIN (SEMI) (Cost=14 Card=18 Bytes=630)
   2 1 TABLE ACCESS (FULL) OF 'tb_user' (Cost=8 Card=8556 Byt
          es=188232)

   3 1 VIEW OF 'VW_NSO_1' (Cost=3 Card=18 Bytes=234)
   4 3 CONNECT BY (WITH FILTERING)
   5 4 NESTED LOOPS
   6 5 INDEX (UNIQUE SCAN) OF 'PK_tb_role' (UNIQUE)
           (Cost=1 Card=1 Bytes=5)

   7 5 TABLE ACCESS (BY USER ROWID) OF 'tb_role'
   8 4 NESTED LOOPS
   9 8 BUFFER (SORT)
  10 9 CONNECT BY PUMP
  11 8 TABLE ACCESS (BY INDEX ROWID) OF 'tb_role' (
          Cost=3 Card=18 Bytes=162)

  12 11 INDEX (RANGE SCAN) OF 'INX_tb_role_PARENT_
          ID' (NON-UNIQUE) (Cost=1 Card=18)





Statistics
----------------------------------------------------------
          0 recursive calls
          0 db block gets
      10250 consistent gets          
          0 physical reads
          0 redo size
     224163 bytes sent via SQL*Net to client
       6553 bytes received via SQL*Net from client
        559 SQL*Net roundtrips to/from client
         17 sorts (memory)
          0 sorts (disk)
       8369 rows processed
论坛徽章:
76
双子座
日期:2015-07-28 14:26:072012新春纪念徽章
日期:2012-02-13 15:09:52ITPUB十周年纪念徽章
日期:2011-11-01 16:21:15鲜花蛋
日期:2011-08-26 02:02:24管理团队成员
日期:2011-05-07 01:45:082010广州亚运会纪念徽章:皮划艇
日期:2011-04-18 11:24:412011新春纪念徽章
日期:2011-02-18 11:43:342011新春纪念徽章
日期:2011-01-25 15:42:562011新春纪念徽章
日期:2011-01-25 15:42:332011新春纪念徽章
日期:2011-01-25 15:42:15
2#
 楼主| 发表于 2008-4-14 11:15 | 只看该作者
exists 用到了nested loops
in用上了 hash join

使用道具 举报

回复
论坛徽章:
0
3#
发表于 2008-4-14 11:22 | 只看该作者
In和exists使用及性能分析(三):in和exists的性能分析
http://space6212.itpub.net/post/12157/242077

使用道具 举报

回复
论坛徽章:
76
双子座
日期:2015-07-28 14:26:072012新春纪念徽章
日期:2012-02-13 15:09:52ITPUB十周年纪念徽章
日期:2011-11-01 16:21:15鲜花蛋
日期:2011-08-26 02:02:24管理团队成员
日期:2011-05-07 01:45:082010广州亚运会纪念徽章:皮划艇
日期:2011-04-18 11:24:412011新春纪念徽章
日期:2011-02-18 11:43:342011新春纪念徽章
日期:2011-01-25 15:42:562011新春纪念徽章
日期:2011-01-25 15:42:332011新春纪念徽章
日期:2011-01-25 15:42:15
4#
 楼主| 发表于 2008-4-14 11:30 | 只看该作者
原帖由 weilaiyxj 于 2008-4-14 11:22 发表
In和exists使用及性能分析(三):in和exists的性能分析
http://space6212.itpub.net/post/12157/242077


谢谢,还是没找到答案 现在两个表数据量差不多,为什么用in 比 exists效率好那么多  9.2.0.4  cbo 模式下

使用道具 举报

回复
招聘 : Java研发
论坛徽章:
71
马上加薪
日期:2014-02-19 11:55:14蜘蛛蛋
日期:2012-12-26 18:16:01茶鸡蛋
日期:2012-11-16 08:12:48ITPUB 11周年纪念徽章
日期:2012-10-09 18:05:07奥运会纪念徽章:网球
日期:2012-08-23 14:58:08奥运会纪念徽章:沙滩排球
日期:2012-07-19 17:28:14版主2段
日期:2012-07-07 02:21:02咸鸭蛋
日期:2012-03-23 18:17:482012新春纪念徽章
日期:2012-02-13 15:13:512012新春纪念徽章
日期:2012-02-13 15:13:51
5#
发表于 2008-4-14 11:39 | 只看该作者
原帖由 paulyibinyi 于 2008-4-14 11:15 发表
exists 用到了nested loops
in用上了 hash join

exists用的filter

使用道具 举报

回复
论坛徽章:
25
ITPUB新首页上线纪念徽章
日期:2007-10-20 08:38:442010世博会纪念徽章
日期:2010-07-30 12:07:232011新春纪念徽章
日期:2011-02-18 11:43:332010广州亚运会纪念徽章:高尔夫球
日期:2011-04-11 18:22:37蜘蛛蛋
日期:2011-08-17 08:44:40ITPUB十周年纪念徽章
日期:2011-11-01 16:21:15复活蛋
日期:2011-12-15 09:06:552012新春纪念徽章
日期:2012-01-04 11:51:22ITPUB 11周年纪念徽章
日期:2012-10-09 18:06:202013年新春福章
日期:2013-02-25 14:51:24
6#
发表于 2008-4-14 11:40 | 只看该作者
原帖由 paulyibinyi 于 2008-4-14 11:15 发表
exists 用到了nested loops
in用上了 hash join

in 里面多了个 VIEW OF 'VW_NSO_1' 与tb_user hash_join,而exists里不存在这个VIEW,而是作为filter,但没想到有这么大的consistents gets!

使用道具 举报

回复
论坛徽章:
76
双子座
日期:2015-07-28 14:26:072012新春纪念徽章
日期:2012-02-13 15:09:52ITPUB十周年纪念徽章
日期:2011-11-01 16:21:15鲜花蛋
日期:2011-08-26 02:02:24管理团队成员
日期:2011-05-07 01:45:082010广州亚运会纪念徽章:皮划艇
日期:2011-04-18 11:24:412011新春纪念徽章
日期:2011-02-18 11:43:342011新春纪念徽章
日期:2011-01-25 15:42:562011新春纪念徽章
日期:2011-01-25 15:42:332011新春纪念徽章
日期:2011-01-25 15:42:15
7#
 楼主| 发表于 2008-4-14 11:44 | 只看该作者
原帖由 anlinew 于 2008-4-14 11:39 发表

exists用的filter



tks,为什么区别这么大

使用道具 举报

回复
论坛徽章:
19
ITPUB新首页上线纪念徽章
日期:2007-10-20 08:38:44ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:06:13BLOG每日发帖之星
日期:2010-03-28 01:01:02ITPUB9周年纪念徽章
日期:2010-10-08 09:31:222012新春纪念徽章
日期:2012-01-04 11:51:22
8#
发表于 2008-4-14 11:44 | 只看该作者

回复 #1 paulyibinyi 的帖子

E:study resB19306_01server.10214211sql_1016.htm#i30971
In certain circumstances, it is better to use IN rather than EXISTS. In general, if the selective predicate is in the subquery, then use IN. If the selective predicate is in the parent query, then use EXISTS.

oracle文档上有详细的描述的,可以参考下,并且有例子的

使用道具 举报

回复
论坛徽章:
76
双子座
日期:2015-07-28 14:26:072012新春纪念徽章
日期:2012-02-13 15:09:52ITPUB十周年纪念徽章
日期:2011-11-01 16:21:15鲜花蛋
日期:2011-08-26 02:02:24管理团队成员
日期:2011-05-07 01:45:082010广州亚运会纪念徽章:皮划艇
日期:2011-04-18 11:24:412011新春纪念徽章
日期:2011-02-18 11:43:342011新春纪念徽章
日期:2011-01-25 15:42:562011新春纪念徽章
日期:2011-01-25 15:42:332011新春纪念徽章
日期:2011-01-25 15:42:15
9#
 楼主| 发表于 2008-4-14 11:46 | 只看该作者
原帖由 microsoft_fly 于 2008-4-14 11:40 发表

in 里面多了个 VIEW OF 'VW_NSO_1' 与tb_user hash_join,而exists里不存在这个VIEW,而是作为filter,但没想到有这么大的consistents gets!


谢谢 分析的很仔细

使用道具 举报

回复
招聘 : Java研发
论坛徽章:
71
马上加薪
日期:2014-02-19 11:55:14蜘蛛蛋
日期:2012-12-26 18:16:01茶鸡蛋
日期:2012-11-16 08:12:48ITPUB 11周年纪念徽章
日期:2012-10-09 18:05:07奥运会纪念徽章:网球
日期:2012-08-23 14:58:08奥运会纪念徽章:沙滩排球
日期:2012-07-19 17:28:14版主2段
日期:2012-07-07 02:21:02咸鸭蛋
日期:2012-03-23 18:17:482012新春纪念徽章
日期:2012-02-13 15:13:512012新春纪念徽章
日期:2012-02-13 15:13:51
10#
发表于 2008-4-14 11:49 | 只看该作者
原帖由 shiri512003 于 2008-4-14 11:44 发表
E:study resB19306_01server.10214211sql_1016.htm#i30971
In certain circumstances, it is better to use IN rather than EXISTS. In general, if the selective predicate is in the subquery, then use IN. If the selective predicate is in the parent query, then use EXISTS.

oracle文档上有详细的描述的,可以参考下,并且有例子的

这个例子不太符合这个role

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表