使用多个OR缓慢INNER JOIN

时间:2017-01-04 19:18:48

标签: mysql sql performance

我试图做这样的事情:

SELECT attr1, attr2, attr3, ...
FROM table1 t1
INNER JOIN table2 t2 ON (
    (t1.a = t2.a OR t1.b = t2.b OR t1.c = t2.c) AND
    (t1.d = t2.d OR t1.e = t2.e OR t1.f = t2.f)

此查询的性能非常差,并且ON子句中的列都不是PK。什么是改善此查询的好方法?

2 个答案:

答案 0 :(得分:3)

这会很慢。更快的方法是多个left join s:

select t1.*, t2.?, t3.?, t4.? . . 
from t1 left join
     t2 t2a
     on t1.a = t2a.a left join
     t2 t2b
     on t1.b = t2b.b left join
     . . .
where t2a.a is not null or t2b.b is not null or t2c.c is not null or . . .

这可以利用t2(a)t2(b)上的单独的索引,依此类推。

请注意,结果集略有不同。假设每列最多支付一个匹配,您将获得一个输出行上给定行的所有匹配。

答案 1 :(得分:0)

另一个选择是为每个连接组合创建一个查询(其中9个)并将它们组合在一起:

SELECT attr1, attr2, attr3, ...
FROM table1 t1
INNER JOIN table2 t2 ON 
    (t1.a = t2.a) AND
    (t1.d = t2.d)

UNION

SELECT attr1, attr2, attr3, ...
FROM table1 t1
INNER JOIN table2 t2 ON 
    (t1.a = t2.a) AND
    (t1.e = t2.e)
UNION

...

UNION

SELECT attr1, attr2, attr3, ...
FROM table1 t1
INNER JOIN table2 t2 ON 
    (t1.c = t2.c) AND
    (t1.f = t2.f)

这样,您可以在每个列对上创建复合索引。 (A,D),(A,E)......(C,F)