首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 .NET Java 游戏 视频 人才 外包 培训 数据库 书店 程序员
中国软件网
欢迎您:游客 | 登录 注册 帮助
  • oracle执行计划疑问 [已结贴,结贴人:47522341]
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • 47522341
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    • 揭帖率:
    发表于:2008-05-07 10:58:35 楼主
    SELECT a.empno
    FROM dept b, emp a, salgrade c
    WHERE EXISTS (SELECT a.empno
                  FROM dept b, emp a, salgrade c
                  WHERE a.deptno=b.deptno
                  AND a.job <> 'CLERK'
                  AND a.sal BETWEEN c.losal AND c.hisal)
    AND a.deptno=b.deptno
    AND a.job <> 'CLERK'
    AND a.sal between losal and hisal;

    OPTIMIZER_GOAL is set to RULE.


    Query Without Hints
    ===================

    The execution path for this query without the use of any hints...:

    Execution Plan
    ----------------------------------------------------------
      0      SELECT STATEMENT Optimizer=RULE
      1    0  FILTER
      2    1    MERGE JOIN
      3    2      SORT (JOIN)
      4    3        NESTED LOOPS
      5    4          TABLE ACCESS (FULL) OF 'SALGRADE'
      6    4          TABLE ACCESS (FULL) OF 'EMP'
      7    2      SORT (JOIN)
      8    7        TABLE ACCESS (FULL) OF 'DEPT'
      9    1    MERGE JOIN
      10    9      SORT (JOIN)
      11  10        NESTED LOOPS
      12  11          TABLE ACCESS (FULL) OF 'SALGRADE'
      13  11          TABLE ACCESS (FULL) OF 'EMP'
      14    9      SORT (JOIN)
      15  14        TABLE ACCESS (FULL) OF 'DEPT'
    ----------------------------------------
    我的问题是
    1,在上述执行计划中怎么可以看出哪个表是driving table ,哪个是proble table;
    2,另外哪几个步骤是外部查询的执行计划,哪几个步骤是内部查询的执行计划?
    100  修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • hebo2005
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    • 3

      2

    发表于:2008-05-07 11:06:071楼 得分:15
    一般你不指定基础表,默认是最右边的,在你的sql里,就是salgrade表
    你的执行计划里好多全表扫描噢
    都不做索引的啊?
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • 47522341
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-05-07 11:14:182楼 得分:0
    没做索引,这个不是实际数据。我就是没看懂在执行计划中驱动表在哪个位置
    ,还有就是根据执行计划怎么能看出oracle的实际执行步骤。

    按照楼上的说法,salgrade是驱动表
    我有点没想通,按照下面的连接条件a.sal between c.losal and c.hisal
    使用c作为驱动好像不太合适吧?
    oracle怎么能根据c表的losal和hisal去连接a表呢?
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • 47522341
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-05-07 11:15:343楼 得分:0
    我有点想当然,觉得既然连接条件是a.sal between c.losal and c.hisal
    那么是不是应该以a表做驱动去遍历查询c表比较合适一些?
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • hebo2005
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    • 3

      2

    发表于:2008-05-07 11:25:444楼 得分:0
    oracle默认规则,以from 之后最右边的表做为基础表,其它表与基础表进行关联比较
    所以一般会把数据量最小的表放在最右边,如果是交叉表,就把交叉表放在最后
    不过你以手动指定基础表的
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • doer_ljy
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-05-07 14:29:545楼 得分:15
    引用 4 楼 hebo2005 的回复:
    oracle默认规则,以from 之后最右边的表做为基础表,其它表与基础表进行关联比较
    所以一般会把数据量最小的表放在最右边,如果是交叉表,就把交叉表放在最后
    不过你以手动指定基础表的

    在optimizer_mode = rule的情况下,
    驱动表的判断确实如此。
    如果在optimizer_mode不是rule那就另当别论了。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • hebo2005
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    • 3

      2

    发表于:2008-05-07 14:32:506楼 得分:0
    引用 5 楼 doer_ljy 的回复:
    引用 4 楼 hebo2005 的回复:
    oracle默认规则,以from 之后最右边的表做为基础表,其它表与基础表进行关联比较 
    所以一般会把数据量最小的表放在最右边,如果是交叉表,就把交叉表放在最后 
    不过你以手动指定基础表的

    在optimizer_mode = rule的情况下,
    驱动表的判断确实如此。
    如果在optimizer_mode不是rule那就另当别论了。

    YES
    你可以用HINT来指定基础表
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • cenlmmx
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    • 3

    发表于:2008-05-07 14:46:537楼 得分:25
    9    1    MERGE JOIN
      10    9      SORT (JOIN)
      11  10        NESTED LOOPS
      12  11          TABLE ACCESS (FULL) OF 'SALGRADE'
      13  11          TABLE ACCESS (FULL) OF 'EMP'
      14    9      SORT (JOIN)
      15  14        TABLE ACCESS (FULL) OF 'DEPT' 
    --------------------------
    it is very clear in plan.
    step 1: dept full scan
    step 2: sort
    step 3: salgrade full scan
    step 4: emp full scan
    step 5: Nest loop from step3 and step4
    step 6: sort
    step 7: Merge join from step2 and step6
    ...
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • cenlmmx
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    • 3

    发表于:2008-05-07 14:48:318楼 得分:0
    little mistake
    step 1: dept full scan
    step 2: sort
    step 3: emp full scan
    step 4: salgrade full scan
    step 5: Nest loop from step3 and step4
    step 6: sort
    step 7: Merge join from step2 and step6
    ...
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • chenhongxin
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-05-07 14:49:439楼 得分:0
    楼上果然狠人,没错的,就是这样的,以前我也不太明白这个..
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • 47522341
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-05-07 16:43:4610楼 得分:0
    9    1    MERGE JOIN 
      10    9      SORT (JOIN) 
      11  10        NESTED LOOPS 
      12  11          TABLE ACCESS (FULL) OF 'SALGRADE' 
      13  11          TABLE ACCESS (FULL) OF 'EMP' 
      14    9      SORT (JOIN) 
      15  14        TABLE ACCESS (FULL) OF 'DEPT' 
    --------------------------
    step 1: dept full scan
    step 2: sort
    step 3: emp full scan
    step 4: salgrade full scan
    step 5: Nest loop from step3 and step4
    step 6: sort
    step 7: Merge join from step2 and step6 
    -----------------------------------------------------------
    如果我没理解错的话,cenlmmx 的意思是不是说在执行计划中靠下的表为驱动表?
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • 47522341
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-05-07 16:49:0011楼 得分:0
    执行顺序我能看出来,现在的疑惑在于下面的嵌套循环中哪个表在前面,哪个在后面?
              NESTED LOOPS 
      12  11          TABLE ACCESS (FULL) OF 'SALGRADE' 
      13  11          TABLE ACCESS (FULL) OF 'EMP' 
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • 47522341
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-05-07 17:01:4012楼 得分:0
    根据前面两列的数字特点,我感觉这个执行计划有点类似一颗执行树,而这个树的执行顺序应该从叶子节点开始。
    按照这个原则,下面执行计划的步骤应该跟cenlmmx 的说法有点出入
    9    1    MERGE JOIN 
      10    9      SORT (JOIN) 
      11  10        NESTED LOOPS 
      12  11          TABLE ACCESS (FULL) OF 'SALGRADE' 
      13  11          TABLE ACCESS (FULL) OF 'EMP' 
      14    9      SORT (JOIN) 
      15  14        TABLE ACCESS (FULL) OF 'DEPT'   
    -------------------------- 
    step 1: salgrade full scan 
    step 2: emp full scan
    step 3: Nest loop from step1 and step2
    step 4: sort 
    step 5: dept full scan 
    step 6: sort 
    step 7: Merge join from step4 and step6 
    ---------------------------------------
    不知道我理解的对不对,
    按照我这种理解方式,驱动表应该是在执行计划中靠上面的数据源,也就是在执行计划树中靠左面的节点。
    这种方式比较容易让人理解和接收。
    从后到前的话,就是说用树的右节点作为驱动节点,好像跟习惯不符
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • cenlmmx
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    • 3

    发表于:2008-05-07 17:17:3413楼 得分:0
    如果我没理解错的话,cenlmmx 的意思是不是说在执行计划中靠下的表为驱动表?
    -------------------------------
    yes,driving table is the table which is scanned firstly in plan.

    现在的疑惑在于下面的嵌套循环中哪个表在前面,哪个在后面?
              NESTED LOOPS 
      12  11          TABLE ACCESS (FULL) OF 'SALGRADE' 
      13  11          TABLE ACCESS (FULL) OF 'EMP' 
    ---------------------------
    of course, emp first,salgrade is second.

    As I am working on server now, so only write EN, sorry.

    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • star_guan2008
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-05-08 09:24:2814楼 得分:0
    关注
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • 47522341
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-05-08 09:39:2815楼 得分:0
    to cenlmmx :非常感谢您热心参与。
    我看到两篇观点一致的资料,其执行顺序都跟您在这里描述的有所偏差。

    总结两个资料的共同点和您的观点,
    共同点在于oracle会根据左面两列的序号建立执行计划树,然后按照后序遍历的方法执行,就是先左子节点,后右子节点,最后是根节点。

    而现在的矛盾点在树中左子节点和右子节点在执行计划中的位置。
    我看到的两篇资料中认为在执行计划中序号靠前的为子节点,根据这种观点建立的计划树应该是:
    9    1    MERGE JOIN 
      10    9      SORT (JOIN) 
      11  10        NESTED LOOPS 
      12  11          TABLE ACCESS (FULL) OF 'SALGRADE' 
      13  11          TABLE ACCESS (FULL) OF 'EMP' 
      14    9      SORT (JOIN) 
      15  14        TABLE ACCESS (FULL) OF 'DEPT' 

                                1
                                  9
              10                               14
              11
    12              13                            15
    这样执行起来步骤就是12,13,11,10,15,14,9,1

    而您的观点好像是直接将执行计划顺时针旋转90度得到执行树,这样的话建立的树应该是
                                    1
                                9
            14                                      10
            15                                      11
                                          13                12
    这时执行的步骤应该是15,14,13,12,11,10,9,1
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • 47522341
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-05-08 09:48:2016楼 得分:0
    to cenlmmx:首先感谢关注
    刚查过两篇观点相似的资料,根你在这里描述的说法有一致但也有偏差。

    首先,观点统一的部分应该是oracle会按照执行计划中左面两列建立一个执行树,然后对执行树执行后序遍历以执行树中的步骤,观点差异在于树建立的时候子节点在执行计划中的位置。
    -----------------------------------
    针对这里描述的执行计划:
    9    1    MERGE JOIN   
      10    9      SORT (JOIN)   
      11  10        NESTED LOOPS   
      12  11          TABLE ACCESS (FULL) OF 'SALGRADE'   
      13  11          TABLE ACCESS (FULL) OF 'EMP'   
      14    9      SORT (JOIN)   
      15  14        TABLE ACCESS (FULL) OF 'DEPT'   
    cenlmmx的观点认为树应该是直接将执行计划顺时针旋转90度得到,这样建立的执行计划树应该是
                    1
                  9
        14                10
        15                11
                        13  12
    后序遍历上面的树得到的执行顺序应该是  15,14,13,12,11,10,19,1
    ----------------------------------------------
    另外一种观点是按照步骤在执行计划中出现的顺序确定其在执行计划中的位置,先出现的为左子节点,这样建立的计划树应该是
                    1
                  9
        10              14
        11              15
      12  13
    后序遍历上面的树得到的执行顺序应该是 12,13,11,10,15,14,9,1
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • dobetterthatnthink
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-05-08 10:01:0117楼 得分:0
    这有什么好说的,缩进越多就是越先开始的步骤,如果还不明了,可以在pl/sql developer plan窗口看,在那里你可以从第一步骤浏览到最后一个步骤,否则缩进还有什么意义?
    其次驱动表,在oracle高版本已经不怎么提倡了,因为在高版本下,优化模式和以前版本有很大区别,只要按照执行计划再结合实际语句你就知道sql语句是如何执行的了。

    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • cenlmmx
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    • 3

    发表于:2008-05-08 11:29:3818楼 得分:45
    哦,应该是我搞错了,你说的第二种观点是正确的.
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • hebo2005
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    • 3

      2

    发表于:2008-05-08 11:49:1319楼 得分:0
    看了下,应该还是以SALGRADE为基础表(应该就是你们说的驱动表)
    我对执行计划还停留的初步的,看是否有全表扫描之类的
    对怎么看执行计划的执行顺序还不太了解,看了上面星星的解释,学了不少
    修改 删除 举报 引用 回复

    网站简介广告服务网站地图帮助联系方式诚聘英才English 问题报告
    北京创新乐知广告有限公司 版权所有 京 ICP 证 070598 号
    世纪乐知(北京)网络技术有限公司 提供技术支持
    Copyright © 2000-2008, CSDN.NET, All Rights Reserved