解决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
)
相关推荐
慕木兮人可14 分钟前
Docker部署MySQL镜像
spring boot·后端·mysql·docker·ecs服务器
{⌐■_■}1 小时前
【Kafka】登录日志处理的三次阶梯式优化实践:从同步写入到Kafka多分区批处理
数据库·分布式·mysql·kafka·go
isNotNullX1 小时前
数据中台架构解析:湖仓一体的实战设计
java·大数据·数据库·架构·spark
kfepiza3 小时前
Debian10安装Mysql5.7.44 笔记250707
笔记·mysql·debian
armcsdn4 小时前
基于Docker Compose部署Traccar容器与主机MySQL的完整指南
mysql·docker·容器
睿思达DBA_WGX4 小时前
由 DB_FILES 参数导致的 dg 服务器无法同步问题
运维·数据库·oracle
袋鼠云数栈5 小时前
使用自然语言体验对话式MySQL数据库运维
大数据·运维·数据库·后端·mysql·ai·数据治理·数栈·data+ai
渣渣盟5 小时前
掌握MySQL函数:高效数据处理指南
sql·mysql·adb·dba
阿里云大数据AI技术5 小时前
数据 + 模型 驱动 AI Native 应用发展
大数据·数据库·人工智能
铅笔侠_小龙虾6 小时前
Docker 实战 -- Mysql
mysql·docker·容器