应用游标优化SQL

本文介绍了一个SQL查询性能从3小时优化到5分钟的实际案例。通过分析发现,原SQL查询涉及大量PGA内存消耗,并存在表分区及子查询等问题。最终通过引入游标及临时表的方式解决了性能瓶颈。

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

问题描述:
公司的一个sql平常都是运行一个小时的,突然有一天3个小时还不能出来,
sql如下:
open cursor for SELECT PROVCODE,
       AREACODE,
       COUNT(DISTINCT USERNUMBER) MON_USERCOUNT,
       SUM(LOGINCOUNT) AS MON_TOTALCOUNT
  FROM oss03.OSS_SSOLOGIN_MON_DETAIL A,
       (SELECT B.SITE_ID
          FROM oss03.OSS_SITES_CLASS_INFO B
         WHERE B.SITE_ID <> -1
           AND B.TYPE_ID = 1) C
 WHERE A.MONTHNO = 201104
   AND A.CLIENTIDEXT = C.SITE_ID
   AND A.LOGINSERVICEID = 10
 GROUP BY A.PROVCODE, A.AREACODE
很多人喜欢在游标后面很长的一个查询
这个sql原来跑2个小时,优化完之后5分钟了
 
分析:
========
tom说游标性能差,那不是主要的,tom只是说了一方面,没讲另外一方面
 
使用游标两个优点: 
1.减少锁得持有时间 
2.减少undo的持有时间
 
对于超过100万的dml,大家需要用游标,游标比sql块主要是快在解析这块 
大事物的sql对性能影响非常大,有些人喜欢写300行的sql,或者更多 
第一这个sql审核太麻烦
第二个:有隐藏的性能问题
 
oss03.OSS_SSOLOGIN_MON_DETAIL 这个表有分区,大概分区对应的有5000万数据 
另外一个表是500万吧 ,这里由于有group by,distinct这些操作都是在用户的pga里面操作 
还有子查询的结果集,hash连接空间 ,都在pga里面
 
优化方法:
==========
分析思维: 由于hash 关联和group by 的时候都会占用pga,且sql未执行之前不会释放,导致pga不足,写临时表操作。
优化的方法是: 加一个出口 
  
先用游标定义结果集 ,然后在运算的时候使用一个临时表排出:

  
然后对这个临时表再次使用游标:
  
整个耗时5分钟就可以了,而且后续跑的都是非常稳定

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值