我正在尝试运行此查询:
select * from matrix where (id1, id2) in ((1,2), (3,5));
但它极其缓慢。 (id1,id2)是主键,所以这应该是一个快速查找。查询规划器失败了吗?
解释说:
| 1 | SIMPLE | s1_movie | ALL | NULL | NULL | NULL | NULL | 48768876 | Using where |
其中48768876是其扫描的行数。
如果我只搜索'in'中的1个项目,我在解释中得到rows = 1,这是正确的,因为它应该只是一个查找。
这是表格:
CREATE TABLE s1_movie (
id1 INT NOT NULL,
id2 INT NOT NULL,
freq INT NOT NULL,
diff FLOAT NOT NULL,
PRIMARY KEY (id1, id2)
) ENGINE=INNODB;
我如何快速做到这一点?好像查询规划器失败了。
谢谢,
乔恩
答案 0 :(得分:0)
您可以将WHERE拆分为两个单一查找部分,或者将它们组合在一起,但如果您不总是有两个选项,那么这将无法管理。
答案 1 :(得分:0)
问题在于您执行IN()语句的方式。 “IN”为“OR”语句提供了另一种语法。问题在于它强制进行全表扫描,这不允许索引完成它们的工作。
相反,将其分解为较小的SELECT语句,并使用UNION聚合结果。这将使您的索引更具相关性。
我不能完全按照你编写示例的方式来说明你在做什么,但是这样的事情:
SELECT * FROM matrix WHERE col1 = var1 AND col2 = var2
UNION
SELECT " FROM matrix WHERE col1 = var3 AND col2 = var4
答案 2 :(得分:0)
供讨论的样本
CREATE TABLE s1_movie (
id1 INT NOT NULL,
id2 INT NOT NULL,
freq INT NOT NULL,
diff FLOAT NOT NULL,
PRIMARY KEY (id1, id2)
) ENGINE=INNODB;
insert into s1_movie select 1,2,3,4;
insert into s1_movie select 1,3,3,4;
insert into s1_movie select 1,4,3,4;
insert into s1_movie select 1,5,3,4;
insert into s1_movie select 1,6,3,4;
insert into s1_movie select 1,7,3,4;
insert into s1_movie select 1,8,3,4;
insert into s1_movie select 1,9,3,4;
insert into s1_movie select 1,0,3,4;
insert into s1_movie select 2,2,3,4;
insert into s1_movie select 2,3,3,4;
比较
explain extended
select * from s1_movie where (id1, id2) = (1,2) or (id1,id2) = (3,5);
和
explain extended
select * from s1_movie where (id1, id2) in ((1,2), (3,5));
元组很漂亮不是吗? MySQL处理元组很好,尽管Mark的答案猜测是问题所在。问题是IN子句。