我正在运行一个看起来像这样的查询
SELECT parent.field, child.field
FROM parent
JOIN child ON (child.id = parent.id
OR child.id = parent.otherid)
然而,这是非常慢的(大约100k记录,并且JOIN到真实版本中的其他表),但尽管尝试了索引
parent.id (PRIMARY),
parent.otherid,
child.id (PRIMARY),
and a composite index of parent.id and parent.otherid
在进行此连接时,我无法让MySQL使用任何这些索引.
我读到MySQL每个连接只能使用一个索引,但是当JOIN包含OR条件时,它是否可以在任何地方找到它是否可以使用复合索引.
有没有人知道是否可以使此查询引用索引?
如果是这样,怎么样?
我的解决方案
(所以我不会让我回答下面的问题)
一堆调整,并提出了一个相当不错的解决方案,保留了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
对于速度需要子查询中的条件来减少放置在临时表中的记录数,但是我在外部查询上有大量额外的连接,一些连接到子节点,一些连接到父节点(有一些聚合)所以这一个最适合我.
在许多情况下,联合将更快,更有效,但由于我在父级上过滤,但是想要从子级(父级自引用)获得额外的数据,因此联合为我创造了额外的行,我无法合并.
有可能只能通过将父级连接到自身并在外部查询中使用where条件别名来找到相同的结果,但是这个对我很有效.
感谢Jirka对UNION ALL的建议,这是促使我到达这里的原因:)
解决方法:
您的查询使得理论上可能单个孩子有两个不同的父母,这将使其成为非常不标准的术语.但是,我们假设您的数据模式使这种情况变得不可能.
然后,下面使用单独的索引给出相同的结果,每列一个索引.
SELECT parent.field, child.field
FROM parent
JOIN child ON child.id = parent.id
UNION ALL
SELECT parent.field, child.field
FROM parent
JOIN child ON child.id = parent.otherid