查看: 15725|回复: 23

[SQL] 【讨论】SQL优化请教(connect by start with相关)

[复制链接]
论坛徽章:
8
马上有房
日期:2014-10-17 16:12:52优秀写手
日期:2014-12-06 06:00:14暖羊羊
日期:2015-03-04 14:54:572015年新春福章
日期:2015-03-06 11:59:47目光如炬
日期:2015-06-07 22:00:00秀才
日期:2015-07-14 09:44:30秀才
日期:2015-11-23 09:48:22狮子座
日期:2016-01-25 13:38:55
跳转到指定楼层
1#
发表于 2014-12-26 14:13 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
SQL优化,connect by start with 相关,start with 后面跟子句查询会很慢 走全表扫描,但是跟常量字符串又很快
1.这个运行正常
SELECT LEVEL
        , LPAD(PARTS_CODE, LENGTH (PARTS_CODE) + (LEVEL * 2 ) - 2 , ' ') PARTS_CODE
        , DESCRIPTION
        ,COMPONTNT_QUANTITY
        ,GP_FLAG
        ,OPERATION_SEQ_NUM
        ,MFG_CODE
        ,PARTS_CODE
        , PRIOR MFG_CODE
        ,CONNECT_BY_ROOT MFG_CODE AS ROOT_NAME
FROM   (SELECT MSI1.SEGMENT1         PARTS_CODE
                    ,MSI1.DESCRIPTION
                    ,MSI2.SEGMENT1         MFG_CODE
                    ,IC.COMPONENT_QUANTITY COMPONTNT_QUANTITY
                    ,IC.OPERATION_SEQ_NUM
                    ,IC.ATTRIBUTE11        GP_FLAG
             FROM   BOM_BILL_OF_MATERIALS    BOM
                    ,BOM_INVENTORY_COMPONENTS IC
                    ,MTL_SYSTEM_ITEMS         MSI1
                    ,MTL_SYSTEM_ITEMS         MSI2
             WHERE  MSI1.INVENTORY_ITEM_ID = IC.COMPONENT_ITEM_ID
             AND    MSI1.ORGANIZATION_ID = BOM.ORGANIZATION_ID
             AND    IC.BILL_SEQUENCE_ID = BOM.BILL_SEQUENCE_ID
             AND    BOM.ORGANIZATION_ID = 105
             AND    BOM.ALTERNATE_BOM_DESIGNATOR = 'MPL'
             AND    BOM.ORGANIZATION_ID = MSI2.ORGANIZATION_ID
             AND    BOM.ASSEMBLY_ITEM_ID = MSI2.INVENTORY_ITEM_ID
             AND    IC.EFFECTIVITY_DATE <= SYSDATE
             AND    (IC.DISABLE_DATE IS NULL OR IC.DISABLE_DATE >= SYSDATE ))
start with MFG_CODE in ( 'ABC' )   --主要问题在这里
CONNECT BY PRIOR PARTS_CODE = MFG_CODE

执行计划截图如下:


2.如果这个限制条件改为一个子查询,效率就会变得十分低下
实际用的时候我从另外一个表直接select MFG_CODE,但是跑了很久就是跑不出
SELECT LEVEL
        , LPAD(PARTS_CODE, LENGTH (PARTS_CODE) + (LEVEL * 2 ) - 2 , ' ') PARTS_CODE
        , DESCRIPTION
        ,COMPONTNT_QUANTITY
        ,GP_FLAG
        ,OPERATION_SEQ_NUM
        ,MFG_CODE
        ,PARTS_CODE
        , PRIOR MFG_CODE
        ,CONNECT_BY_ROOT MFG_CODE AS ROOT_NAME
FROM   (SELECT MSI1.SEGMENT1         PARTS_CODE
                    ,MSI1.DESCRIPTION
                    ,MSI2.SEGMENT1         MFG_CODE
                    ,IC.COMPONENT_QUANTITY COMPONTNT_QUANTITY
                    ,IC.OPERATION_SEQ_NUM
                    ,IC.ATTRIBUTE11        GP_FLAG
             FROM   BOM_BILL_OF_MATERIALS    BOM
                    ,BOM_INVENTORY_COMPONENTS IC
                    ,MTL_SYSTEM_ITEMS         MSI1
                    ,MTL_SYSTEM_ITEMS         MSI2
             WHERE  MSI1.INVENTORY_ITEM_ID = IC.COMPONENT_ITEM_ID
             AND    MSI1.ORGANIZATION_ID = BOM.ORGANIZATION_ID
             AND    IC.BILL_SEQUENCE_ID = BOM.BILL_SEQUENCE_ID
             AND    BOM.ORGANIZATION_ID = 105
             AND    BOM.ALTERNATE_BOM_DESIGNATOR = 'MPL'
             AND    BOM.ORGANIZATION_ID = MSI2.ORGANIZATION_ID
             AND    BOM.ASSEMBLY_ITEM_ID = MSI2.INVENTORY_ITEM_ID
             AND    IC.EFFECTIVITY_DATE <= SYSDATE
             AND    (IC.DISABLE_DATE IS NULL OR IC.DISABLE_DATE >= SYSDATE ))
start with MFG_CODE in ( select 'ABC' from dual )  --改了个子查询就很慢,整个执行计划都变了
CONNECT BY PRIOR PARTS_CODE = MFG_CODE
执行计划截图如下:有hash jion 还有全表扫描



大家有空的帮忙看看,如何把第二SQL的执行计划跑的和第一个1一样啊,感激不尽啊~
求职 : 数据库开发
论坛徽章:
29
ITPUB学员
日期:2009-10-14 18:49:45至尊黑钻
日期:2015-12-31 11:11:56数据库板块每日发贴之星
日期:2009-10-22 01:01:02优秀写手
日期:2014-04-30 06:00:17ITPUB8周年纪念徽章
日期:2009-10-09 21:30:10秀才
日期:2017-05-17 11:39:09马上有车
日期:2014-10-09 10:14:53马上有钱
日期:2014-02-18 16:43:09路虎
日期:2013-10-15 15:38:59林肯
日期:2013-09-12 15:57:33
2#
发表于 2014-12-26 14:28 | 只看该作者
所有的object_name里的名字都带着_B。。可是SQL里的表跟执行计划里的名字不一样啊

使用道具 举报

回复
论坛徽章:
8
马上有房
日期:2014-10-17 16:12:52优秀写手
日期:2014-12-06 06:00:14暖羊羊
日期:2015-03-04 14:54:572015年新春福章
日期:2015-03-06 11:59:47目光如炬
日期:2015-06-07 22:00:00秀才
日期:2015-07-14 09:44:30秀才
日期:2015-11-23 09:48:22狮子座
日期:2016-01-25 13:38:55
3#
 楼主| 发表于 2014-12-26 14:35 | 只看该作者
风铃中の鬼 发表于 2014-12-26 14:28
所有的object_name里的名字都带着_B。。可是SQL里的表跟执行计划里的名字不一样啊

不好意思额,不带B的这些都是同义词,忽略好了,实际表都是带_B的

使用道具 举报

回复
论坛徽章:
6
2010广州亚运会纪念徽章:板球
日期:2010-11-15 11:29:572010广州亚运会纪念徽章:足球
日期:2010-11-15 11:30:022013年新春福章
日期:2013-02-25 14:51:24优秀写手
日期:2013-12-20 06:00:12沸羊羊
日期:2015-03-04 14:51:522015年新春福章
日期:2015-03-06 11:57:31
4#
发表于 2014-12-26 14:47 | 只看该作者
使用cardinality提示呢?
如select /*+ cardinality( a, 1) */ 'ABC' from dual a;

使用道具 举报

回复
论坛徽章:
8
马上有房
日期:2014-10-17 16:12:52优秀写手
日期:2014-12-06 06:00:14暖羊羊
日期:2015-03-04 14:54:572015年新春福章
日期:2015-03-06 11:59:47目光如炬
日期:2015-06-07 22:00:00秀才
日期:2015-07-14 09:44:30秀才
日期:2015-11-23 09:48:22狮子座
日期:2016-01-25 13:38:55
5#
 楼主| 发表于 2014-12-26 14:58 | 只看该作者
abstractcyj 发表于 2014-12-26 14:47
使用cardinality提示呢?
如select /*+ cardinality( a, 1) */ 'ABC' from dual a;

还是不行,我今天试了好多hint 结果还是走全表扫描

使用道具 举报

回复
求职 : 数据库开发
论坛徽章:
29
ITPUB学员
日期:2009-10-14 18:49:45至尊黑钻
日期:2015-12-31 11:11:56数据库板块每日发贴之星
日期:2009-10-22 01:01:02优秀写手
日期:2014-04-30 06:00:17ITPUB8周年纪念徽章
日期:2009-10-09 21:30:10秀才
日期:2017-05-17 11:39:09马上有车
日期:2014-10-09 10:14:53马上有钱
日期:2014-02-18 16:43:09路虎
日期:2013-10-15 15:38:59林肯
日期:2013-09-12 15:57:33
6#
发表于 2014-12-26 14:59 | 只看该作者
本帖最后由 风铃中の鬼 于 2014-12-26 15:13 编辑
风铃中の鬼 发表于 2014-12-26 14:28
所有的object_name里的名字都带着_B。。可是SQL里的表跟执行计划里的名字不一样啊

不知道为什么要用同义词。。看执行计划。。也没显示出跨库来。。这样。。你试试把内联视图拿出来用with as写进去。。with t as (select ...)select ... from t connect by ...看看能不能避免条件内推

使用道具 举报

回复
论坛徽章:
8
马上有房
日期:2014-10-17 16:12:52优秀写手
日期:2014-12-06 06:00:14暖羊羊
日期:2015-03-04 14:54:572015年新春福章
日期:2015-03-06 11:59:47目光如炬
日期:2015-06-07 22:00:00秀才
日期:2015-07-14 09:44:30秀才
日期:2015-11-23 09:48:22狮子座
日期:2016-01-25 13:38:55
7#
 楼主| 发表于 2014-12-26 15:18 | 只看该作者
风铃中の鬼 发表于 2014-12-26 14:59
不知道为什么要用同义词。。看执行计划。。也没显示出跨库来。。这样。。你试试把内联视图拿出来用with a ...

这个我也不太清楚,因为是ERP的主物料表,很多地方都是用同义词引用的

使用道具 举报

回复
论坛徽章:
6
2014年新春福章
日期:2014-02-18 16:49:31马上有钱
日期:2014-02-18 16:49:31优秀写手
日期:2014-02-21 06:00:13马上有车
日期:2014-10-09 10:14:53技术图书徽章
日期:2017-07-12 17:18:46妮可·罗宾
日期:2017-08-10 12:13:56
8#
发表于 2014-12-26 22:48 | 只看该作者
为啥要定义一个相同的表:MTL_SYSTEM_ITEMS         MSI2
AND    BOM.ORGANIZATION_ID = MSI2.ORGANIZATION_ID
AND    BOM.ASSEMBLY_ITEM_ID = MSI2.INVENTORY_ITEM_ID

使用道具 举报

回复
论坛徽章:
6
2014年新春福章
日期:2014-02-18 16:49:31马上有钱
日期:2014-02-18 16:49:31优秀写手
日期:2014-02-21 06:00:13马上有车
日期:2014-10-09 10:14:53技术图书徽章
日期:2017-07-12 17:18:46妮可·罗宾
日期:2017-08-10 12:13:56
9#
发表于 2014-12-26 23:08 | 只看该作者
IN 用 EXIST 呢

使用道具 举报

回复
论坛徽章:
6
2014年新春福章
日期:2014-02-18 16:49:31马上有钱
日期:2014-02-18 16:49:31优秀写手
日期:2014-02-21 06:00:13马上有车
日期:2014-10-09 10:14:53技术图书徽章
日期:2017-07-12 17:18:46妮可·罗宾
日期:2017-08-10 12:13:56
10#
发表于 2014-12-26 23:09 | 只看该作者
风铃中の鬼 发表于 2014-12-26 14:28
所有的object_name里的名字都带着_B。。可是SQL里的表跟执行计划里的名字不一样啊

同感,看执行计划 差点被吓住了

使用道具 举报

回复

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

本版积分规则 发表回复

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