2011-03-09 59 views
1

我试图运行此查询:mysql的不充分利用主键 “SELECT * from表where(COL,COL)在”

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项,我在explain中得到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

这有点冒失,但你可以做一个有效的SELECT的'UNION',例如, '(SELECT * FROM matrix WHERE id1 = 1 AND id2 = 2)UNION(SELECT * FROM matrix WHERE id1 = 3 AND id2 = 5)' – 2011-03-09 22:38:13

+1

为什么'matrix'变成's1_movie'? – RichardTheKiwi 2011-03-09 22:38:32

回答

0

您可以在WHERE分成逻辑或在一起的两个单查找零件,但将变得难以控制,如果你并不总是有两个选择。

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 
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); 

And

explain extended 
select * from s1_movie where (id1, id2) in ((1,2), (3,5)); 

元组很漂亮是不是他们?尽管Mark的答案是猜测问题,MySQL仍然可以很好地处理元组。问题是IN子句。

+0

这仍然是缓慢的... – tpow 2011-03-09 22:43:29

+0

@cinqoTimo请扩大评论,为什么它“仍然缓慢”?它的执行方式与您的UNION完全相同(应该是UNION ALL btw) – RichardTheKiwi 2011-03-09 22:45:26

+0

Richard - 我的错,我在看错误的查询。你重写了语法,这是最后一个片段,所以我认为这是你的答案。 – tpow 2011-03-09 22:48:31

相关问题