实战 | 搞定“in”值过多导致的慢SQL问题,你可以这样做……

这篇具有很好参考价值的文章主要介绍了实战 | 搞定“in”值过多导致的慢SQL问题,你可以这样做……。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

实战 | 搞定“in”值过多导致的慢SQL问题,你可以这样做……

在最近的某财政项目中,达梦的性能监控工具定位了一些慢SQL问题。针对这些问题,达梦专家和应用厂商一起采用了创建索引、优化视图、引进临时表等方法进行优化。

下面我们将展示一个典型问题——由“in”值过多导致的慢SQL,让我们一起来看看,高手是如何用达梦特有的事务级临时表解决的。

问题详情


在前段时间的项目中,出现了一个很典型的查询优化问题。在此跟大家分享问题分析及解决方法。

此例中SQL文本大小达1.8MB,如下:

select
        count(1)
from
        V_XXXXXXXXXXXXXX t
where
                                        C1= '235432'
                                    and C2= '345436'
    and
        (
                C3  = 'SADFDSGADFDSAFDSAFSAD'
             or C3 is null
        )
    and
        (
          id in ('ERTRTEWEB4DF2BE413523615EFDBA', 
              'ERTETRET2A7C44AE83EFEC5DD4169FA2', 'FF053E459ERTRETRETR755D70B6C1712', 
              '057ERWTETETRETRETRRRD8738ED5D886', '0518C9DERWTRETRETREE63B5346B38B3', 
              '3E50D3EF6ERTRERTRTREE6920014CD55', '421FA8BERTERTEWTEWRTREA1181A059A', 
              '31E2F34EWRTREWRTE31F72CA0563E4C9', '356EWRTREWTREWGFD1BE5DB4A4A39BEE', 
                 ................此处省略数万行
              '8BEE2AERTEWTR70885B6421166C3A6C5', '296E705ERTRETWHG456196D973439599')
        )

这是一个多表连接的比较复杂的视图,SQL的过滤条件里id列 “in” 了几万个常量(红框部分)。这条语句第一次执行需要12秒,第二次执行时间为毫秒级。

原因分析


上述两次执行时间的差别,说明该语句执行时间主要消耗在SQL硬解析上。由于项目中相关功能的并发量较大,这条慢SQL引发了严重的性能问题。

这个问题比较普遍。主要原因是开发人员图简单,对“in”列表里常量的个数没有评估。常量动辄数万,甚至数十万,这种SQL在并发量较大的情况下就是灾难。

优化思路


1. 创建一个事务级的临时表

CREATE GLOBAL TEMPORARY TABLE TMP_INLIST
(
    ID VARCHAR(100)
 
) ON COMMIT DELETE ROWS;

2. 将需要参与过滤的常量值插入临时表

--addBatch()批量绑定参数
INSERT INTO TMP_INLIST VALUES(?);

3. 改写SQL语句

select
        count(1)
from
        V_XXXXXXXXXXXXXX t
where
                                        C1= '235432'
                                    and C2= '345436'
    and
        (
                C3  = 'SADFDSGADFDSAFDSAFSAD'
             or C3 is null
        )
    and
        (
          id in (select id from TMP_INLIST)
        );

解决效果


按上述优化思路处理后,不管“in”列表里面有多少个常量,SQL解析的代价都是一样的,性能问题得到解决。在本例中,此条SQL首次执行时间由十几秒降至毫秒级文章来源地址https://www.toymoban.com/news/detail-425023.html

到了这里,关于实战 | 搞定“in”值过多导致的慢SQL问题,你可以这样做……的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • el-select选项过多导致页面卡顿,路由跳转卡顿

    1.使用Virtualized Select 虚拟化选择器,页面就不卡了 2.el-select做分页,后端可能会不太想改,可以按照需求用computer做分页 3.可以使用滚动加载与自定义筛选 我看过的文章1:解决el-select数据量过大导致页面卡顿 文章2:el-select选项过多导致卡顿的解决方案 文章3:对el-select进行

    2024年01月24日
    浏览(29)
  • 一张图解决vue中websocket推送数过多导致页面卡主(思路)

    首先,websocket连接就不过多赘述了,主要讲述连接以后出现的问题,这个问题点就在于渲染,websocket推送在数据量过大时不能一条一条渲染,这样会导致浏览器压力过大而崩溃(卡死),所以主要思路就是将数据缓存在一个数组中,通过定时器定时渲染数据。 下面是逻辑代码

    2024年02月11日
    浏览(37)
  • 前端 CSS - 如何隐藏右侧的滚动条 -关于出现过多的滚动条导致界面不美观

    CSS 配置:下面两个一起写进进去,适配 IE、火狐、谷歌浏览器 1. 网页设计之隐藏浏览器垂直的滚动条

    2024年02月10日
    浏览(64)
  • Hadoop集群/Zookeeper服务启动失败(Unable to write in /tmp等问题)----虚拟机内存问题导致

    一、问题描述:1.输入命令start-all.sh正常启动集群时 出现以下图片报错: 2.或在正常启动zookeeper服务时zkServer.sh start后发现内存不足报错,导致zookeeper服务启动失败。 以上两个问题都是因为根目录内存不足所导致服务启动失败 二、问题查找分析: 查看分区状况 根目录在/de

    2024年04月14日
    浏览(50)
  • Redis缓存设计与性能优化【缓存和数据库不一致问题,解决方案:1.加过期时间这样可以一段时间后自动刷新 2.分布式的读写锁】

    在大并发下,同时操作数据库与缓存会存在数据不一致性问题 1、双写不一致情况 2、读写并发不一致 解决方案: 1、对于并发几率很小的数据(如个人维度的订单数据、用户数据等),这种几乎不用考虑这个问题,很少会发生缓存不一致, 可以给缓存数据加上过期时间,每隔一

    2024年04月13日
    浏览(51)
  • 【Android】 频繁刷新 RecyclerView导致View 对象引用过多引起的Native 内存占用过大解决办法

    在 RecyclerView 中,如果频繁刷新 RecyclerView,可能会导致 Native 内存中有大量的 TextView 对象,从而导致内存占用过多的问题。以下是一些可能导致该问题的原因和解决方法: 使用 ViewHolder 在 RecyclerView 中,使用 ViewHolder 可以避免频繁创建和销毁 View 对象,从而减少内存占用。可

    2024年02月08日
    浏览(72)
  • 【安全】mybatis中#{}和${}导致sql注入问题及解决办法

    使用mybatis的时候遇到了#{}和${}可能导致sql注入的问题 #{} 底层通过prepareStatement对当前传入的sql进行了预编译,一个 #{ } 被解析为一个参数占位符 ?; #{} 解析之后会将String类型的数据自动加上引号,其他数据类型不会 #{} 很大程度上可以防止sql注入(sql注入是发生在编译的过程

    2024年01月19日
    浏览(37)
  • 【Java】mybatis中#{}和${}导致sql注入问题及解决办法

    使用mybatis的时候遇到了#{}和${}可能导致sql注入的问题 #{} 底层通过prepareStatement对当前传入的sql进行了预编译,一个 #{ } 被解析为一个参数占位符 ?; #{} 解析之后会将String类型的数据自动加上引号,其他数据类型不会 #{} 很大程度上可以防止sql注入(sql注入是发生在编译的过程

    2024年01月17日
    浏览(43)
  • SQL Server事务执行过程中中释放锁导致的死锁问题 - 排查与分析

    系统的某个用来上报数据的接口存在死锁的问题。这个接口内部对多张表进行了Update操作,执行顺序为A表、B表、C表、D表、A表。死锁发生的SQL,一条是第一次更新A表的SQL,另一条是第二次更新A表的SQL。整个更新都处在一个事务内,理论上讲,只要第一个Session开始执行事务

    2024年02月02日
    浏览(53)
  • 有了WebRTC,直播可以这样玩

    如何实现两个人的实时视频通话呢?你可能会首先想到直播手段:采流 - 推流 - 拉流。但是,如果把这个过程放在前端去实现,那只能天台见了。然而,WebRTC的出现,扭转了这个现状。 借助WebRTC,前端可以不用去关注“采流 - 推流 - 拉流”这种过程,倾轻松就可以实现直播甚

    2023年04月16日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包