ITPUB论坛-中国最专业的IT技术社区

 找回密码
 注册
查看: 744|回复: 7

[SQL] 求助,怎么优化带有多个exists语句,调整过滤顺序

[复制链接]
论坛徽章:
8
2014年新春福章
日期:2014-02-18 16:50:09马上有车
日期:2014-02-18 16:50:09优秀写手
日期:2014-05-16 06:00:302014年世界杯参赛球队: 瑞士
日期:2014-06-06 13:30:382014年世界杯参赛球队: 法国
日期:2014-06-13 11:24:50巨蟹座
日期:2015-08-09 10:01:31马上加薪
日期:2014-11-04 14:21:17复活蛋
日期:2014-12-01 15:10:24
发表于 2017-12-3 18:32 | 显示全部楼层 |阅读模式
SELECT billing_cycle_id,month_id,settle_detail_id,cust_id,section_id,order_finish_date,calc_charge,prd_inst_id,service_nbr,prd_id,prd_completed_date,real_sett_cycle_id,sett_flag,reason
  from settle_order_detail_795 a  
    where a.month_id=201711
and exists(SELECT 1 from serv_mon_795_disconnect b,TB_CRMDB_CUST_201711 c
      where a.cust_id=c.cust_id and c.certi_number=b.certi_number
       and months_between( to_date('201711','yyyymm'),to_date(b.month_id,'yyyymm') ) = any(0,1,2))
and a.prd_id = 80000045
and a.month_id=substr(a.prd_completed_date,0,6)
and a.sett_flag<>3
and not exists (select 1 from tb_pty_agent_ofr_type_rel e
where a.cur_ofr_id = e.ofr_id  and e.ref_dem_type_id = any (1049,1050,1057,1058) )
and not exists (SELECT 1 from serv_mon_795_201711 d
where a.prd_inst_id = d.serv_id and d.payment_mode = 1 )

QQ截图20171203182929.png

怎么修改SQL,让它最后才去过滤  not exists (SELECT 1 from serv_mon_795_201711 d
where a.prd_inst_id = d.serv_id and d.payment_mode = 1 ) ;因为前面所有的执行都很快,执行出来的结果集也就100多条数据,但一加上最后那个 not exists 语句就好慢。
尝试写了 /*+leading(a,c,b)*/ 仍然没效果。


认证徽章
论坛徽章:
168
SQL数据库编程大师
日期:2016-01-13 10:30:43SQL极客
日期:2013-12-09 14:13:35SQL大赛参与纪念
日期:2013-12-06 14:03:45最佳人气徽章
日期:2015-03-19 09:44:03现任管理团队成员
日期:2015-08-26 02:10:00秀才
日期:2015-07-28 09:12:12举人
日期:2015-07-13 15:30:15进士
日期:2015-07-28 09:12:58探花
日期:2015-07-28 09:12:58榜眼
日期:2015-08-18 09:48:03
发表于 2017-12-4 15:57 | 显示全部楼层
两个计划发出来

使用道具 举报

回复
认证徽章
论坛徽章:
8
2009新春纪念徽章
日期:2009-01-04 14:52:28祖国60周年纪念徽章
日期:2009-10-09 08:28:002010新春纪念徽章
日期:2010-03-01 11:07:24ITPUB9周年纪念徽章
日期:2010-10-08 09:32:25ITPUB十周年纪念徽章
日期:2011-11-01 16:23:262013年新春福章
日期:2013-02-25 14:51:24沸羊羊
日期:2015-03-04 14:51:522015年新春福章
日期:2015-03-06 11:57:31
发表于 2017-12-4 19:04 来自手机 | 显示全部楼层
各表多少数据?各子查询返回多少数据?

使用道具 举报

回复
论坛徽章:
480
榜眼
日期:2015-09-09 10:34:21秀才
日期:2015-11-23 10:03:12秀才
日期:2015-11-23 10:03:12秀才
日期:2015-11-23 10:03:12秀才
日期:2015-11-23 10:03:12秀才
日期:2015-11-23 10:03:12秀才
日期:2015-11-23 10:03:12秀才
日期:2015-11-23 10:03:12状元
日期:2015-11-23 10:04:09举人
日期:2015-11-23 10:04:09
发表于 2017-12-4 22:23 | 显示全部楼层
既然已经知道去掉这个条件会很快而且结果很小,那么就用 WITH tmp_data as (SELECT /*+ MATERIALIZE */ .... --- 去掉NOT EXIST的其他部分)
然后在此基础上再加上NOT EXISTS条件。

使用道具 举报

回复
认证徽章
论坛徽章:
8
2009新春纪念徽章
日期:2009-01-04 14:52:28祖国60周年纪念徽章
日期:2009-10-09 08:28:002010新春纪念徽章
日期:2010-03-01 11:07:24ITPUB9周年纪念徽章
日期:2010-10-08 09:32:25ITPUB十周年纪念徽章
日期:2011-11-01 16:23:262013年新春福章
日期:2013-02-25 14:51:24沸羊羊
日期:2015-03-04 14:51:522015年新春福章
日期:2015-03-06 11:57:31
发表于 2017-12-5 15:52 | 显示全部楼层
试试这个呢:
SELECT /*+ no_push_subq(@subq1)*/ billing_cycle_id,month_id,settle_detail_id,cust_id,section_id,order_finish_date,calc_charge,prd_inst_id,service_nbr,prd_id,prd_completed_date,real_sett_cycle_id,sett_flag,reason
  from settle_order_detail_795 a  
    where a.month_id=201711
and exists(SELECT 1 from serv_mon_795_disconnect b,TB_CRMDB_CUST_201711 c
      where a.cust_id=c.cust_id and c.certi_number=b.certi_number
       and months_between( to_date('201711','yyyymm'),to_date(b.month_id,'yyyymm') ) = any(0,1,2))
and a.prd_id = 80000045
and a.month_id=substr(a.prd_completed_date,0,6)
and a.sett_flag<>3
and not exists (select 1 from tb_pty_agent_ofr_type_rel e
where a.cur_ofr_id = e.ofr_id  and e.ref_dem_type_id = any (1049,1050,1057,1058) )
and not exists (SELECT /*+ no_unnest qb_name(subq1)*/ 1 from serv_mon_795_201711 d
where a.prd_inst_id = d.serv_id and d.payment_mode = 1 )

使用道具 举报

回复
论坛徽章:
8
2014年新春福章
日期:2014-02-18 16:50:09马上有车
日期:2014-02-18 16:50:09优秀写手
日期:2014-05-16 06:00:302014年世界杯参赛球队: 瑞士
日期:2014-06-06 13:30:382014年世界杯参赛球队: 法国
日期:2014-06-13 11:24:50巨蟹座
日期:2015-08-09 10:01:31马上加薪
日期:2014-11-04 14:21:17复活蛋
日期:2014-12-01 15:10:24
 楼主| 发表于 2017-12-6 10:38 | 显示全部楼层
sqysl 发表于 2017-12-5 15:52
试试这个呢:
SELECT /*+ no_push_subq(@subq1)*/ billing_cycle_id,month_id,settle_detail_id,cust_id,s ...

谢谢。可行。 QQ截图20171206103611.png
很快了。

使用道具 举报

回复
论坛徽章:
8
2014年新春福章
日期:2014-02-18 16:50:09马上有车
日期:2014-02-18 16:50:09优秀写手
日期:2014-05-16 06:00:302014年世界杯参赛球队: 瑞士
日期:2014-06-06 13:30:382014年世界杯参赛球队: 法国
日期:2014-06-13 11:24:50巨蟹座
日期:2015-08-09 10:01:31马上加薪
日期:2014-11-04 14:21:17复活蛋
日期:2014-12-01 15:10:24
 楼主| 发表于 2017-12-6 10:46 | 显示全部楼层
newkid 发表于 2017-12-4 22:23
既然已经知道去掉这个条件会很快而且结果很小,那么就用 WITH tmp_data as (SELECT /*+ MATERIALIZE */ ... ...

谢谢,你的方法更简便。可行。 2.png

使用道具 举报

回复
论坛徽章:
20
ITPUB元老
日期:2005-02-28 12:57:002012新春纪念徽章
日期:2012-02-13 15:10:582012新春纪念徽章
日期:2012-02-13 15:10:582012新春纪念徽章
日期:2012-02-13 15:10:582012新春纪念徽章
日期:2012-02-13 15:10:58马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:142012新春纪念徽章
日期:2012-02-13 15:10:58
发表于 2017-12-8 14:52 | 显示全部楼层
Try this product, you will get a solution automatically:

https://tosska.com/tosska-sql-tuning-expert-tse-oracle/

使用道具 举报

回复

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

本版积分规则

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