解决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
)
相关推荐
九皇叔叔8 分钟前
深度拆解MySQL InnoDB存储引擎架构:从内存到磁盘的全链路解析
mysql·innodb·存储引擎
Sunia15 分钟前
《Spring AI + 大模型全栈实战》学习手册系列 · 专题二:《Milvus 向量数据库:从零开始搭建 RAG 系统的核心组件》
数据库
絆人心23 分钟前
最新 SQL 常用语句大全(新手入门 + 老手速查,含 DQL/DML/DDL)
数据库·sql·oracle
keyborad pianist39 分钟前
一篇文章学会Redis
数据库·redis·缓存
星辰_mya40 分钟前
SQL 性能调优:EXPLAIN 详解与慢查询优化案例
数据库·sql·面试·架构师
xixingzhe240 分钟前
spring boot druid 10秒超时问题
java·数据库·spring boot
IndulgeCui42 分钟前
Kingbase 身份认证与权限控制实践—数据库安全的第一道防线
数据库
AAA_搬砖达人小郝42 分钟前
SQL 高级查询技巧:WITH + UNION ALL + EXISTS + WHERE TRUE/FALSE 联合实战
数据库·sql
Yushan Bai42 分钟前
RAC环境数据库节点异常重启问题的分析(存储光纤信号问题)
数据库
WINDHILL_风丘科技1 小时前
FlexPro高级应用之模板定制
数据库·汽车·汽车测试·flexpro