MySQL IN运算符替代

时间:2016-10-28 11:25:01

标签: mysql

在我的查询中,我必须找到以下逗号分隔ID的所有记录。

2,20,44,66,68,85,90,101,102,103,125,168

所以我为任务编写了以下查询

SELECT item_id, 
       item_name 
FROM   `items` 
WHERE  `item_id` IN ( 2, 20, 44, 66, 
                      68, 85, 90, 101, 
                      102, 103, 125, 168 ) 
但问题是,当逗号分隔的ID列表很大时,查询执行时间会变大。还有其他方法可以完成我的任务。

DESCRIBE表查询后的我的表结构如下。请检查

Field   Type    Null    Key Default Extra   
asheet_id   int(11) unsigned    NO  PRI NULL    auto_increment
asheet_staff_id int(11) unsigned    NO      NULL    
asheet_exam_number  int(11) NO      NULL    

2 个答案:

答案 0 :(得分:0)

item_id是主键吗?

执行:

DESCRIBE items;

并将结果置于问题

1)如果YES那么调查你服务器的内存,查询缓存,查询并发,网络/套接字连接等因素。也许慢部分不是你的查询,而是在你的应用程序的另一部分?所以请在问题/评论中描述你如何检查它。 看看my.cnf有很多可以帮助你调整mysql性能的参数。

2)如果NO添加索引:ALTER TABLE items ADD INDEX item_id_index (item_id)

如果:您的items表格不会经常UPDATE查询,最好将引擎更改为MyISAM,它是&#39 ; SELECT查询的速度很快<

我还要说让我们尝试以下技巧:

1)UNION SELECT包含每个ID,因为如果它的PK它将作为SELECT ... LIMIT 1使用:

SELECT item_id, item_name FROM  items WHERE item_id = 2
UNION ALL
SELECT item_id, item_name FROM  items WHERE item_id = 20
UNION ALL
.
.
UNION ALL
SELECT item_id, item_name FROM  items WHERE item_id = 168

2)创建一个视图并将您的查询发送给它:

CREATE OR REPLACE VIEW vw_items AS 
SELECT item_id, item_name FROM items;

SELECT * FROM vw_items WHERE item_id IN (...);

如果您的数据库有很多请求,并且items表确实有更新查询,请尝试使用memcacheredis

将查询缓存到数据库

P.S。执行JOINsub query操作无法获得性能,因为在这两种情况下,它都会在item_id字段上使用相同的索引。

答案 1 :(得分:0)

另一种方法是创建Temporary Table,使用这些数据填充该表,然后执行JOIN之类的

create temporary table test(Id int);

insert into test
select 2
union
select 99 from dual;

然后执行与该表的连接

SELECT i.item_id, i.item_name 
FROM  `items` i
JOIN test t ON i.item_id = t.Id;

这种方法比拥有一个巨大的IN列表更好,因为列表中的内容会在内部变为扁平OR条件,而且每个RDBMS都限制{{1}中的元素数量}(不确定IN但是说MySQL限制为5000个元素左右。)

相反,执行NETEZZA会产生一个高效的执行计划。如果JOIN,您也可以选择使用SQL Server