使用带有OR条件的MySQL JOIN中的索引

我正在运行一个看起来像这样的查询

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
上一篇:为什么MySQL并不总是在这里使用索引合并?


下一篇:python – 有没有办法按索引合并多个列表索引?