【SQL优化】子查询展开

本文分享了一篇关于SQL优化的经验,重点讨论了如何将子查询展开,以提升查询性能。通过实例展示了子查询展开在实际应用中的价值,旨在帮助开发者优化数据库查询效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

下面是很早之前的优化例子,一直保存在本地笔记中,今天分享出来:


交谈中请勿轻信汇款、中奖信息、陌生电话,勿使用外挂软件。

xxx网友  19:06:29
哪位大哥大姐帮我优化一下SQl 我数据记录太多 加载不了啊
我  19:07:43
可以贴上来研究哈
xxx网友  19:07:57
select (select org_name from o_org where org_no = k.org_no) a,
       mr_sect_no b,
     (select name from r_sect where mr_sect_no = k.mr_sect_no) c,
       cons_no d,
       cons_name e,
       elec_addr f
  from c_cons k
 where exists
 (select 1
          from c_cons_prc h
         where cons_id = k.cons_id
           and prc_code in 
               (SELECT P.PRC_CODE
                  FROM E_BILL_PARA_VER PARA, e_cat_prc P, e_prc_scope q
                 WHERE P.CAT_PRC_ID = q.CAT_PRC_ID
                   and PARA.PAR_VER_TYPE = 1
                   AND PARA.RELEASE_FLAG = '1'
                   AND (TRUNC(SYSDATE) BETWEEN PARA.PAR_BGN_DATE AND
                       PARA.PAR_END_DATE)
                   and PARA.PARA_VN = P.para_vn
                   and q.policy_type_code = 3
                ))
   and org_no like '4340101%'
   and mr_sect_no =7000001689
prc_code in 
               (SELECT P.PRC_CODE
                  FROM E_BILL_PARA_VER PARA, e_cat_prc P, e_prc_scope q
                 WHERE P.CAT_PRC_ID = q.CAT_PRC_ID
                   and PARA.PAR_VER_TYPE = 1
                   AND PARA.RELEASE_FLAG = '1'
                   AND (TRUNC(SYSDATE) BETWEEN PARA.PAR_BGN_DATE AND
                       PARA.PAR_END_DATE)
                   and PARA.PARA_VN = P.para_vn
                   and q.policy_type_code = 3
                就是因为这段
exists 语句中有in 关键字 子查询
xxx网友  19:09:27
怎么优化一下in 的子查询啊
我用existS 替换in 时间差不多
我  19:10:23
in里面返回多少记录?
可以贴个执行计划上来
xxx网友  19:11:09
不多啊 才28条记录
可是因为这个IN子查询 就足足慢了200倍
有In 6秒多 没有in 0.4秒
我  19:12:19
子查询展开了
加个hint试试
xxx网友  19:12:45
什么意思 什么这是oracle
hint 没见过这个关键字
我  19:14:03
select /*+ NO_UNNEST(@INV) */
 (select org_name from o_org where org_no = k.org_no) a,
 mr_sect_no b,
 (select name from r_sect where mr_sect_no = k.mr_sect_no) c,
 cons_no d,
 cons_name e,
 elec_addr f
  from c_cons k
 where exists
 (select 1
          from c_cons_prc h
         where cons_id = k.cons_id
           and prc_code in
               (SELECT /*+qb_name(inv)*/
                 P.PRC_CODE
                  FROM E_BILL_PARA_VER PARA, e_cat_prc P, e_prc_scope q
                 WHERE P.CAT_PRC_ID = q.CAT_PRC_ID
                   and PARA.PAR_VER_TYPE = 1
                   AND PARA.RELEASE_FLAG = '1'
                   AND (TRUNC(SYSDATE) BETWEEN PARA.PAR_BGN_DATE AND
                       PARA.PAR_END_DATE)
                   and PARA.PARA_VN = P.para_vn
                   and q.policy_type_code = 3))
   and org_no like '4340101%'
   and mr_sect_no = 7000001689


跑一跑
xxx网友  19:16:13
你够牛逼的啊 跟没有in子查询一样快
我  19:16:42
呵呵
一般如果in里面返回比较少
但是有了它有很慢
xxx网友  19:17:09
比没有in 的还快 用了0.3秒多
我  19:17:12
多半是in里面的子查询 被 展开了
要加一个hint让其 不展开
这就是cbo聪明过了头
xxx网友  19:19:17
 /*+qb_name(inv)*/ 这不是注释吗 我怎么没看出你修改什么了
我  19:19:50
确实是注释
不过这个注释是告诉cbo 怎么去处理相关的代码段
而不是想c里面一样的给人看的

xxx网友  19:20:40
哦是这样
这两句注释起的作用 真让我长见识了
xxx网友  19:25:18
太牛了
我  19:26:01
额 这个嘛 小case
xxx网友  19:27:11
帮我解决大事了
xxx网友  19:28:54
 帮我提高了这么多时间 所有问题迎刃而解
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值