我正在运行一个看起来像这样的查询
SELECT parent.field, child.field
FROM parent
JOIN child ON (child.id = parent.id
OR child.id = parent.otherid)
然而,这真的很慢(大约 10 万条记录,并且在真实版本中加入了其他表),但尽管尝试了索引
parent.id (PRIMARY),
parent.otherid,
child.id (PRIMARY),
and a composite index of parent.id and parent.otherid
在进行此连接时,我无法让 MySQL 使用这些索引中的任何一个。
我读到 MySQL 每个连接只能使用一个索引,但是当 JOIN 包含 OR 条件时,它是否可以使用复合索引却找不到任何地方。
这里有谁知道是否可以让这个查询引用索引?如果是这样,怎么做?
我的解决方案
(所以不会让我在 atm 下面回答我自己的问题)
一系列调整并提出了一个相当不错的解决方案,它保留了 JOIN 和聚合其他表的能力。
SELECT parent.field, child.field
FROM parent
JOIN (
SELECT parent.id as parentid,
# Prevents the need to union
IF(NOT ISNULL(parent.otherid) AND parent.otherid <> parent.id,
parent.otherid,
parent.id) as getdataforid
FROM parent
WHERE (condition)
) as foundrecords
ON foundrecords.parentid = parent.id
JOIN child ON child.id = parent.getdataforid
为了速度,子查询中需要一个条件来减少放置在临时表中的记录数量,但是我在外部查询上有大量额外的连接,一些连接到子查询,一些连接到父查询(带有一些聚合)所以这个最适合我。
在许多情况下,联合会更快、更有效,但由于我正在过滤父级,但想要来自子级的额外数据(父级自我引用),联合为我带来了额外的行,我无法合并。只需将 parent 连接到自身并在外部查询中为 where 条件设置别名,就可以找到相同的结果,但这对我来说非常有效。
感谢 Jirka 的 UNION ALL 建议,这就是促使我来到这里的原因:)