楼主: paulyibinyi

请教in和exists的区别

[复制链接]
招聘 : 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
51#
发表于 2008-4-14 15:42 | 只看该作者
原帖由 mihawk 于 2008-4-14 15:26 发表
这个用全表扫描试试

Select /*+full(f)*/ID
From tb_role f
where e.role_id = f.id
Connect By Prior Id = parent_id
Start With Id = 1
/

本来准备建议这样的,但如果这里id=?会变的话,hint也就不一定合适了

使用道具 举报

回复
论坛徽章:
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
52#
 楼主| 发表于 2008-4-14 15:45 | 只看该作者
原帖由 mihawk 于 2008-4-14 15:35 发表
整个语句试试这个(语法等效的, 但是强制使用了hash和full table)

select /*+ordered use_hash(e x)*/
        e.id, e.role_id, e.login
from tb_user e ,
(Select /*+full(f)*/distinct ID
From tb_role f
Connect By Prior Id = parent_id
Start With Id = 1) x
where e.role_id = x.id
/


恩 tks
SQL> select /*+ordered use_hash(e x)*/
  2          e.id, e.role_id, e.login
  3  from tb_user e ,
  4  (Select /*+full(f)*/distinct ID
  5  From tb_role f
  6  Connect By Prior Id = parent_id
  7  Start With Id = 1) x
  8  where e.role_id = x.id
  9  ;

8369 rows selected.


Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=16 Card=8556 Bytes=2
          99460)

   1    0   HASH JOIN (Cost=16 Card=8556 Bytes=299460)
   2    1     TABLE ACCESS (FULL) OF 'tb_user' (Cost=8 Card=8556 Byt
          es=188232)

   3    1     VIEW (Cost=5 Card=8974 Bytes=116662)
   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         HASH JOIN
   9    8           CONNECT BY PUMP
  10    8           TABLE ACCESS (FULL) OF 'tb_role' (Cost=5 Car
          d=8974 Bytes=80766)





Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
        923  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
          9  sorts (memory)
          0  sorts (disk)
       8369  rows processed

SQL>

使用道具 举报

回复
论坛徽章:
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
53#
 楼主| 发表于 2008-4-14 15:47 | 只看该作者
原帖由 anlinew 于 2008-4-14 15:42 发表

本来准备建议这样的,但如果这里id=?会变的话,hint也就不一定合适了


这个会变化的

使用道具 举报

回复
论坛徽章:
0
54#
发表于 2008-4-14 15:47 | 只看该作者

Note 250646.1

Subject:  Upgrading from 8.1.X to 9.X - Subquery Issues - Diagnosing and Resolving
  Doc ID:  Note:258945.1 Type:  TROUBLESHOOTING
  Last Revision Date:  13-JUL-2006 Status:  PUBLISHED

PURPOSE

The Oracle Cost Based Optimizer is continually been enhanced. These enhancements were designed to improve performance but in some cases can cause a minority of queries to perform no better or worse than before. This article discusses some of the potential problems you may encounter when moving SQL Queries from Oracle 8i to Oracle 9i. It mainly centres on changes within the Cost Based Optimizer.
SCOPE & APPLICATION

DBAs and Application Designers
Upgrading from 8.1.X to 9.X - Subquery Issues - Diagnosing and Resolving

Subquery Unnesting Changes

Oracle 9i enabled subquery unnesting by default, controlled by the <Parameter:OPTIMIZER_FEATURES_ENABLE>.
If this was set to >= 9.0.0. then subquery unnesting would be enabled.
This means that on Oracle9i, queries containing subqueries are likely to be unnested when they were not in Oracle8i.

In most cases unnesting subqueries provides performance enhancements, but in some cases unnesting can produce a sub-optimal plan (or other factors, such as missing or innaccurate statistics, can produce a poor plan making the unnesting seem a bad option).

If an application has 8i to 9i upgrade related query tuning problem, please consider if subqueries are involved
Enhanced subquery unnesting

Diagnosing Subquery Unnesting issues:


Look for subqueries in the query text
Examine the explain plan and determine if the subquery has been unnested
Compare the current explain plan with the plan from the earlier version to see if the subquery is being handled differently
Disable subquery unnesting and see if that resolves the problem

To workaround subquery unnesting issues, you may disable unnesting in one of the following ways:


Set <Parameter:UNNEST_SUBQUERY> (underscore) = FALSE

alter session set "_UNNEST_SUBQUERY" = false;

If _unnest_subquery = false does not help then you may also need to set _always_semi_join = off (if the subquery is an IN or EXISTS) or _always_anti_join = off (if the subquery is a NOT IN or NOT EXISTS)

alter session set "_ALWAYS_SEMI_JOIN" = off;
alter session set "_ALWAYS_ANTI_JOIN" = off;


Set <Parameter:OPTIMIZER_FEATURES_ENABLE> to a value less than "9.0.0"
This is a static parameter and cannot be changed on the fly. It has to be set in one of the instance initialisation files (e.g. initSID.ora).
Set <Parameter:UNNEST_NOTEXISTS_SQ> (underscore) = OFF for not exists subqueries.
Use a /*+ NO_UNNEST */ hint in the subquery
Rewrite the query to modify or remove the subquery
Please note that the decision to unnest a subquery is not costed in Oracle9i. The decision to unnest a subquery is taken based on a set of heuristics (rules) before the query is optimized.
RELATED DOCUMENTS


Note 258167.1 Upgrading from 8.1.X to 9.X - Potential Query Tuning Related Issues
Note 144967.1 Manipulating the access path of queries involving subqueries
Note 199070.1 Optimizing statements that contain views or subqueries
@
@ INTERNAL Note 250646.1 SubQuery Unnesting - IN SubQuery
@ INTERNAL Note 258228.1 SubQuery Unnesting - NOT IN SubQuery
@ INTERNAL Note 258676.1 SubQuery Unnesting - EXISTS SubQuery .

使用道具 举报

回复
论坛徽章:
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
55#
发表于 2008-4-14 15:51 | 只看该作者
good job!
自己要学的还很多呀,努力!!!

使用道具 举报

回复
论坛徽章:
0
56#
发表于 2008-4-14 15:52 | 只看该作者
@ INTERNAL Note 250646.1 SubQuery Unnesting - IN SubQuery
@ INTERNAL Note 258228.1 SubQuery Unnesting - NOT IN SubQuery
@ INTERNAL Note 258676.1 SubQuery Unnesting - EXISTS SubQuery
已经找不到了

使用道具 举报

回复
招聘 : 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
57#
发表于 2008-4-14 15:53 | 只看该作者
原帖由 paulyibinyi 于 2008-4-14 15:47 发表


这个会变化的

那么可能大多数情况下nest loop join可能更好了
从sql字面猜测业务逻辑来看,具体如何,还需研究实际业务

使用道具 举报

回复
论坛徽章:
5
生肖徽章2007版:鸡
日期:2008-01-02 17:35:53奥运会纪念徽章:羽毛球
日期:2008-06-23 12:00:05奥运会纪念徽章:柔道
日期:2008-07-04 09:42:36奥运会纪念徽章:皮划艇激流回旋
日期:2008-08-12 14:50:402010新春纪念徽章
日期:2010-03-01 11:19:07
58#
发表于 2008-4-14 15:54 | 只看该作者
原帖由 anlinew 于 2008-4-14 15:42 发表

本来准备建议这样的,但如果这里id=?会变的话,hint也就不一定合适了


猜想:
1. id=?不会变, 因为这个语句应该是取整棵树的数据.
2. 觉得 select id from tb_role都可以解决问题, 而不需要进行递归查询.

不知道楼主的业务逻辑, 仅仅是猜想.

使用道具 举报

回复
论坛徽章:
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
59#
 楼主| 发表于 2008-4-14 16:07 | 只看该作者
原帖由 mihawk 于 2008-4-14 15:54 发表


猜想:
1. id=?不会变, 因为这个语句应该是取整棵树的数据.
是的 但id=经常会变化的 有时从第五层 或其他层开始查
2. 觉得 select id from tb_role都可以解决问题, 而不需要进行递归查询.
这是业务逻辑 需要递归查询 从某个代理下的所有子代理下的所有user

不知道楼主的业务逻辑, 仅仅是猜想.

使用道具 举报

回复
论坛徽章:
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
60#
 楼主| 发表于 2008-4-14 16:10 | 只看该作者
原帖由 anlinew 于 2008-4-14 15:53 发表

那么可能大多数情况下nest loop join可能更好了
从sql字面猜测业务逻辑来看,具体如何,还需研究实际业务

恩 目前生产sql语句没加任何提示,改成in方式查询速度还可以接受

使用道具 举报

回复

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

本版积分规则 发表回复

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