使用 or 优化查询
Posted
技术标签:
【中文标题】使用 or 优化查询【英文标题】:Optimizing query with or 【发布时间】:2013-03-08 16:00:56 【问题描述】:我需要将三个表连接在一起。第一个有 ~100k 行,第二个 ~300k 行,最后一个 ~40 行。第一个和第二个应该由一个复合条件连接,但这是诀窍。查询要求它是OR
条件。由于 OR 条件,索引无法正确使用。我尝试将这两个困难的表分离为两个单独的查询,并用 union 将它们连接起来,以帮助 mysql 找到正确的索引。
我可以做些什么来优化这个查询?
select * from a, b, c where (a.x = b.x OR a.y = b.y) and b.z = c.z
【问题讨论】:
我要做的第一件事是将您的连接条件移动到连接 ON 条件而不是 where 子句 我不确定,现在不能尝试,但我会检查是否有助于将 2 个不同的变体分开? @AarolamaBluenk 我想看一个证明,写所有列名确实更快。 @tombom 使用常识即可。选择单个列而不是所有列,看看结果通过网络传输需要多长时间。 是的,但如果你需要所有列,那也没什么区别。 【参考方案1】:尝试 2 个查询的 UNION:-
select *
from a
INNER JOIN b ON a.x = b.x
INNER JOIN c ON and b.z = c.z
UNION
select *
from a
INNER JOIN b ON a.y = b.y
INNER JOIN c ON and b.z = c.z
(在实际应用中,我同意不使用 SELECT *)
【讨论】:
试过类似的东西。我尝试简化以便将 c 排除在外,但性能仍然很糟糕 这是允许 MySQL 在存在 OR 时使用索引的正常方式。如果它仍然表现不佳,则表明它选择的索引可能很差。你能发布一个解释或你的这个查询的版本吗?【参考方案2】:我会先使用 ANSI 连接语法,然后使用 EXPLAIN
优化查询:
select *
from a
inner join b on a.x = b.x OR a.y = b.y
inner join c on b.z = c.z
【讨论】:
问题是mysql好像不能用OR的复合键 是的,但是如果您在 a.x、a.y、b.x 和 b.y 中的每一个上都有单独的索引,那么 MySQL 应该能够使用索引合并进行连接。你试过吗? 我想我做到了。在某一时刻,我有“所有可能的索引组合”,但 mysql 非常不愿意选择它们。【参考方案3】:你应该这样做
select
[your column names]
from a
inner join b
on a.x = b.x
OR a.y = b.y
inner join c
on b.z = c.z
【讨论】:
以上是关于使用 or 优化查询的主要内容,如果未能解决你的问题,请参考以下文章