使用或条件执行左连接缓慢

Posted

技术标签:

【中文标题】使用或条件执行左连接缓慢【英文标题】:Slow execution of left join with or condition 【发布时间】:2014-12-18 11:09:49 【问题描述】:

我有一个 SQL 查询,它在 or 条件下连接另一个表,如下所示:

select a.id,b.id from a left join b on (b.prop1=a.id or b.prop2=a.id)

1026 rows in set (12.77 sec)

如果我将查询一分为二,没有或条件,它会快得多:

select a.id,b.id from a left join b on (b.prop1=a.id)
1026 rows in set (0.03 sec)

select a.id,b.id from a left join b on (b.prop2=a.id)
1026 rows in set (0.04 sec)

要快得多,但我必须手动合并两个查询的结果。

为什么我的初始查询这么慢?我该怎么做才能让它更快?

我使用的是 mysql 5.5.35

【问题讨论】:

union 会更快吗?如果您在a.id 上有选择,然后在b.id 上有union (全部完全匹配)?您是否还定义了键?还是索引? 是的 or 是杀手。即使它们是 where 子句的一部分,也不能使用索引。另一种方法是使用 union all 和 2 个查询,其中每个连接条件是分开的。 为什么不能或不使用索引?是查询执行器不够聪明还是有更深层次的原因? 相关:***.com/q/34194658/694576 【参考方案1】:

尝试使用UNION 代替OR

select a.id,b.id from a left join b on (b.prop1=a.id)
UNION ALL
select a.id,b.id from a left join b on (b.prop2=a.id)

这应该比OR更快

【讨论】:

这里没有重复的风险?您确定没有行同时具有 b.prop1=a.id 和 b.prop2=a.id? @jarlh UNION ALL 删除重复项。 不知道...你确定吗? UNION ALL 不会删除重复项。 UNION 会。 我告诉过你...在第二次选择中调整为 (b.prop2=a.id and b.prop1 a.id)。

以上是关于使用或条件执行左连接缓慢的主要内容,如果未能解决你的问题,请参考以下文章

灵巧;如何在多个条件下执行左外连接?

mysql连接内连接左连接右连接全连接

SQL Server - 选择左连接 NULL 记录 WHERE 条件

clickhouse : 使用 IN 左连接

Oracle左连接右连接全外连接(+)号作用

外连接查询