相关推荐recommended
mysql的IN查询优化
作者:mmseoamin日期:2024-04-29

mysql的IN里面的数量太大,比如大于1千时,查询的性能就会差很多。

有以下的解决方法

解决方法一:拆分IN的数量

IN 数量超过1千,就拆成多条 sql, 每条sql的IN数量不超过1千。

用OR或者UNION进行SQL改写。

也可以使用 Java写代码,把 IN 数量进行拆分,每条sql的IN数量不超过1千。多次执行。

比如使用 IN 的sql 是

SELECT 字段1 FROM 表名 WHERE 字段2 IN (1,2,3,4,5,...2000)

可以替换成:

SELECT 字段1 FROM 表名 WHERE 字段2 IN (1,2,3,4,5,...1000) 
UNION ALL 
SELECT 字段1 FROM 表名 WHERE 字段2 IN (1001,1002,...2000)

这个方法有个缺点,就是如果 IN 里面的数量太大,比如1万,那么就需要拼接10次。。

解决方法二 :使用 JOIN(关联查询)来代替 IN

可以给字段加上索引,然后使用 JOIN(关联查询)

比如使用 IN 的sql 是:

SELECT 字段  FROM 表名1
WHERE 字段1 IN (SELECT 字段2 FROM 表名2);

可以用关联查询代替为:

SELECT 字段  FROM 表名1
JOIN 表名2
ON 表名1.字段1=表名2.字段2

解决方法三 :使用临时表

创建临时表,当你断开与数据库的连接后,临时表就会自动被销毁。 临时表只在当前连接中有效。

还可以给字段加上索引。

格式:

CREATE TEMPORARY TABLE 临时表名 (id int auto_increment primary key ,
                                            字段名 VARCHAR(长度),
                                          INDEX idx_索引名 (字段名));

然后将表的数据,插入到临时表,格式如下:

INSERT INTO 临时表名(字段名) SELECT 字段 FROM 表名;

然后,再使用OR 或者 JOIN 关联查询。

示例:

CREATE TEMPORARY TABLE temp_table_order (id int auto_increment primary key ,
                                            order_id VARCHAR(32),
                                          INDEX idx_order_id (order_id));
           
INSERT INTO temp_table_order(order_id) SELECT order_id FROM tb_order_detail_test;
           
SELECT *  FROM tb_order_test tb
JOIN temp_table_order tt
ON tb.id=tt.order_id;

如果是比较重要的数据,也可以使用普通的表,持久保存。

参考资料:

sql in 条件超过 1000 怎么办? - 知乎