解决sql查询中in查询项过多时很慢的问题

最近遇到查询一张大数据量表时,需要对一个字段做in查询,in中的元素数量可能达到几千个,即使对这个字段加上索引,速度也慢到无法接受

示例表结构如下:

表中有几十万的数据,且example_id和data_id字段加了联合索引,只做一个简单的select查询:

sql 复制代码
select * from TEST_TABLE01 where example_id=:exampleId and data_id in(:dataIds)

其中in存在1000个元素,查询速度很慢,因为in的个数太多,会全表扫描,导致索引失效。

优化方案:

不使用in语法,将sql语句简化成下面这种,索引就生效了

sql 复制代码
select * from TEST_TABLE01 where example_id=:exampleId and data_id=:dataId

但是这样一次只能查询一条data_id匹配的数据,这就意味着程序要和数据库交互1000次,但是我测试的速度要快于上面的in方式。

进一步优化,减少数据库交互方式,使用union all拼接sql:

sql 复制代码
select * from TEST_TABLE01 where example_id=:exampleId and data_id=:dataId0
union all
select * from TEST_TABLE01 where example_id=:exampleId and data_id=:dataId1
union all
select * from TEST_TABLE01 where example_id=:exampleId and data_id=:dataId2
union all
select * from TEST_TABLE01 where example_id=:exampleId and data_id=:dataId3
...
...
union all
select * from TEST_TABLE01 where example_id=:exampleId and data_id=:dataId999

程序中对dataId的参数进行组装,这样只和数据库交互一次,索引也不会失效,这种方式解决了in查询慢的问题。

对于delete也可以使用类似的方式优化:

sql 复制代码
delete from TEST_TABLE01 a
WHERE exists (
    select * from (
        select * TEST_TABLE01 where example_id=:exampleId and data_id=:dataId0
        union all
        select * TEST_TABLE01 where example_id=:exampleId and data_id=:dataId1
    ) b where a.id=b.id
)
相关推荐
小白男神16 小时前
MySQL进阶学习四(存储过程、游标、触发器)
mysql
这个DBA有点耶16 小时前
MVCC深入:Read View、版本链与快照读——InnoDB并发控制的内核
数据库·mysql·架构
DBA_G16 小时前
从地面到云霄:GBase数据库在民航三大场景的落地实践
数据库
自由能燃气设备16 小时前
商用全预混低氮冷凝锅炉免费方案vs付费方案对比+选型避坑指南
大数据·数据库·人工智能
科创致远17 小时前
科创致远 ESOP 系统核心效能与实战价值展示
大数据·数据库·人工智能·精益工程
漂着的圆木18 小时前
Agent 功能参与度:Copilot 怎么算
sql·数据分析·agent·githubcopilot·度量
kybs199118 小时前
全球灾害数据分析可视化 毕业设计-附源码66794
vue.js·spring boot·mysql·安全·django·c#·asp.net
2601_9622186118 小时前
万象生鲜系统称重自动多退少补算法解决生鲜非标品痛点
大数据·数据库·人工智能·python·算法
程序猿_极客18 小时前
【免费】分享一套优质的基于SSM的校园失物招领系统的设计与实现,源码+文档+视频详解(讲解)
java·mysql·ssm·课程设计·失物招领系统
张洛闻Eren19 小时前
k8s云原生【第十课】:水平 Pod 自动扩缩容
运维·数据库·云原生·kubernetes·github