代码之家  ›  专栏  ›  技术社区  ›  Andrew Cholakian

MySQL中连接中OR的优化

  •  4
  • Andrew Cholakian  · 技术社区  · 16 年前

    我在MySQL中遇到了一个非常复杂的查询,当其中一个连接使用OR完成时,查询速度会急剧减慢。我怎样才能加快速度?相关连接是:

    LEFT OUTER JOIN publications p ON p.id = virtual_performances.publication_id 
                                   OR p.shoot_id = shoots.id
    

    删除OR中的任一条件都会将查询时间从1.5秒缩短到0.1秒。我能想到的所有相关栏目都有索引。有什么想法吗?正在使用的列都有索引。使用EXPLAIN,我发现一旦OR开始起作用,MySQL最终就不会使用任何索引。我可以制作一种特殊的索引吗?

    3 回复  |  直到 16 年前
        1
  •  7
  •   Bill Karwin    16 年前

    OR

    我试着解释一下:假设我让你搜索一本电话簿,找到每个姓“托马斯”的人 他的名字是“托马斯”。尽管电话簿本质上是一个索引,但你并没有从中受益——你必须逐页搜索,因为它不是按 名字

    请记住,在MySQL中,给定查询中的任何表实例都可以使用 只有一个索引 ,即使您在该表中定义了多个索引。如果优化器认为对同一表的不同查询更有帮助,则可以使用另一个索引。

    在像你这样的情况下,人们用来帮助你的一种技巧是 UNION 两个更简单的查询,每个查询都使用单独的索引:

     SELECT ...
     FROM virtual_performances v
     JOIN shoots s ON (...)
     LEFT OUTER JOIN publications p ON (p.id = v.publication_id)
    UNION ALL
     SELECT ...
     FROM virtual_performances v
     JOIN shoots s ON (...)
     LEFT OUTER JOIN publications p ON p.shoot_id = s.id;
    
        2
  •  4
  •   Guffa    16 年前

    select ..., coalesce(p1.field, p2.field) as field
    from ...
    left join publications p1 on p1.id = virtual_performances.publication_id
    left join publications p2 on p2.shoot_id = shoots.id
    
        3
  •  0
  •   coreyward    16 年前

    SELECT * FROM tablename WHERE id IN (SELECT p.id FROM tablename LEFT OUTER JOIN publications p ON p.id IN virtual_performances.publication_id) OR p.id IN (SELECT p.id FROM tablename LEFT OUTER JOIN publications p ON p.shoot_id = shoots.id);