Oracle子查询优化

前言

项目经理扔给我一个需求,说用户反馈用户查询页面转圈圈很久很久,于是我就通过调试去找到请求的路径,找到相关代码,拿到SQL进行字段逐步排查,寻找到卡顿的原因,经我检查发现造成SQL查询慢的原因,如下:

在这里插入图片描述
注释掉卡顿字段SQL后,查询时间如下:
在这里插入图片描述
显而易见,卡的就是我红框圈出来的那块,查询20条数据都需要30秒,如果关联表数据再多点估计就是分钟级别了。

改造

将子查询抽出来,变成左连接查询,查询时间如下:
在这里插入图片描述
查询时间显而易见了,希望此篇文章对你有所帮助。

最后贴出SQL:

优化前
select * from ( select table_A., rownum rownum_A from (select T.,
DECODE( nvl(RA.STATUS_DISPLAY,0), 0, ‘未分配’, ‘已分配’ ) ROLE_STATUS_DISPLAY
from (SELECT USER_ACCOUNT.USER_ACCOUNT_ID, USER_ACCOUNT.ACCOUNT_NAME, USER_ACCOUNT.EMPNO, USER_ACCOUNT.CHANNEL_CODE, USER_ACCOUNT.SURNAME, USER_ACCOUNT.NAME, USER_ACCOUNT.ACCOUNT_TYPE, USER_ACCOUNT.STATUS, USER_ACCOUNT.PWD_STATUS, USER_ACCOUNT.UPDATE_DATE, ORG.ORG_NAME, ( SELECT POSITION.CODENAME FROM T_JOB_LEVEL POSITION WHERE POSITION.CODE = USER_ACCOUNT.JOB_LEVEL ) JOB_LEVEL_DISPLAY, ( SELECT DEV.DEV_CODE FROM PLAT_DEVICE DEV WHERE DEV.USER_ID = USER_ACCOUNT.USER_ACCOUNT_ID ) DEV_CODE FROM PLAT_USER_ACCOUNT USER_ACCOUNT, PLAT_ORG ORG WHERE ORG.ORG_CODE = USER_ACCOUNT.ORG_CODE AND NVL(USER_ACCOUNT.STATUS,1) != 2 AND (USER_ACCOUNT.IS_TEMPORARY=0 OR USER_ACCOUNT.IS_TEMPORARY is null) AND USER_ACCOUNT.CHANNEL_CODE=‘10’ AND USER_ACCOUNT.ORG_CODE IN ( SELECT T.ORG_CODE FROM PLAT_ORG T WHERE 1=1 START WITH ORG_CODE = ‘86’ CONNECT BY PRIOR ORG_CODE = PARENT_ORG_CODE) ) T left join ( SELECT COUNT(AR.ROLE_ID) STATUS_DISPLAY,AR.USER_ACCOUNT_ID USER_ACCOUNT_ID FROM PLAT_ACCOUNT_ROLE AR,PLAT_ROLE R WHERE AR.ROLE_ID = R.ROLE_ID AND NVL(R.STATUS,1) = 1 GROUP BY AR.USER_ACCOUNT_ID ) RA on ra.USER_ACCOUNT_ID = T.USER_ACCOUNT_ID ORDER BY T.UPDATE_DATE, T.NAME DESC) table_A
where rownum <= 20 ) where rownum_A > 0

优化后:
select * from ( select table_A., rownum rownum_A from (select T.,
DECODE( nvl(RA.STATUS_DISPLAY,0), 0, ‘未分配’, ‘已分配’ ) ROLE_STATUS_DISPLAY
from (SELECT USER_ACCOUNT.USER_ACCOUNT_ID, USER_ACCOUNT.ACCOUNT_NAME, USER_ACCOUNT.EMPNO, USER_ACCOUNT.CHANNEL_CODE, USER_ACCOUNT.SURNAME, USER_ACCOUNT.NAME, USER_ACCOUNT.ACCOUNT_TYPE, USER_ACCOUNT.STATUS, USER_ACCOUNT.PWD_STATUS, USER_ACCOUNT.UPDATE_DATE, ORG.ORG_NAME, ( SELECT POSITION.CODENAME FROM T_JOB_LEVEL POSITION WHERE POSITION.CODE = USER_ACCOUNT.JOB_LEVEL ) JOB_LEVEL_DISPLAY, ( SELECT DEV.DEV_CODE FROM PLAT_DEVICE DEV WHERE DEV.USER_ID = USER_ACCOUNT.USER_ACCOUNT_ID ) DEV_CODE FROM PLAT_USER_ACCOUNT USER_ACCOUNT, PLAT_ORG ORG WHERE ORG.ORG_CODE = USER_ACCOUNT.ORG_CODE AND NVL(USER_ACCOUNT.STATUS,1) != 2 AND (USER_ACCOUNT.IS_TEMPORARY=0 OR USER_ACCOUNT.IS_TEMPORARY is null) AND USER_ACCOUNT.CHANNEL_CODE=‘10’ AND USER_ACCOUNT.ORG_CODE IN ( SELECT T.ORG_CODE FROM PLAT_ORG T WHERE 1=1 START WITH ORG_CODE = ‘86’ CONNECT BY PRIOR ORG_CODE = PARENT_ORG_CODE) ) T left join ( SELECT COUNT(AR.ROLE_ID) STATUS_DISPLAY,AR.USER_ACCOUNT_ID USER_ACCOUNT_ID FROM PLAT_ACCOUNT_ROLE AR,PLAT_ROLE R WHERE AR.ROLE_ID = R.ROLE_ID AND NVL(R.STATUS,1) = 1 GROUP BY AR.USER_ACCOUNT_ID ) RA on ra.USER_ACCOUNT_ID = T.USER_ACCOUNT_ID ORDER BY T.UPDATE_DATE, T.NAME DESC) table_A
where rownum <= 20 ) where rownum_A > 0

总结

在编写SQL当中,尽量使用左/右连接,不要使用字段子查询的方式,这样会让你的SQL变得非常之慢(查询速度会随你的用户量倍增)。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Oracle 数据库中的子查询可以提供更为灵活的数据查询和分析功能,但是子查询的性能优化也是我们需要考虑的问题。以下是一些可以优化 Oracle 子查询性能的方法: 1. 使用 EXISTS 替代 IN:在使用子查询时,IN 子句可能会导致性能问题,因为它需要对外部查询和子查询之间的结果集进行比较。使用 EXISTS 替代 IN 可以避免这种情况。 2. 使用 WITH 优化递归查询:对于大型数据集上的递归查询,使用 WITH 可以提高性能。WITH 子句可以在查询中定义一个递归共用表达式,使得查询更加简洁且易于维护。 3. 使用内连接替代子查询:使用内连接可以避免使用子查询时可能出现的性能问题。内连接可以在查询中同时检索两个表的数据,并且效率更高。 4. 使用子查询缓存:Oracle 数据库可以缓存子查询的结果,以便在下次查询时直接从缓存中获取结果。这可以减少查询的时间和资源消耗。 5. 优化索引:在使用子查询时,确保查询的字段都有索引,可以大大提高查询性能。 6. 正确使用 GROUP BY:当使用子查询时,需要正确使用 GROUP BY 子句。如果 GROUP BY 子句使用不当,可能会导致性能问题。因此,需要确保 GROUP BY 子句中的所有字段都在 SELECT 子句中出现。 总之,优化 Oracle 子查询性能需要综合考虑多个因素,包括查询语句的结构、索引、缓存等等。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值