【问题标题】:Why do two joins runs faster than one with an OR condition?为什么两个连接比一个带有 OR 条件的连接运行得更快?
【发布时间】:2014-06-14 09:39:50
【问题描述】:

我正在我的数据库中查询位置列表,这些位置要么是教师的主要位置,要么是教师提供了可用性信息的位置。

如果我像这样进行两次连接:

SELECT tea.*, avail_loc.*, pri_loc.*
FROM teachers AS tea
     LEFT JOIN availability AS ava
            ON(tea.teacher_id = ava.teacher_id AND ava.end_date > 1398706428)
     LEFT JOIN locations AS avail_loc
            ON(ava.location_id = avail_loc.location_id)
     LEFT JOIN locations AS pri_loc
            ON(tea.location_id = pri_loc.location_id)
WHERE tea.active = 1

我的查询需要 0.05 秒。问题是我必须清理 php 中的输出,因为我的位置分为avail_loc(备用位置)和pri_loc(主要位置)。

因此,如果我将它们组合成一个带有 OR 条件的连接,则查询需要 0.8 秒。

SELECT tea.*, loc.*
FROM teachers AS tea
     LEFT JOIN availability AS ava
            ON(tea.teacher_id = ava.teacher_id AND ava.end_date > 1398706428)
     LEFT JOIN locations AS loc
            ON(ava.location_id = loc.location_id OR tea.location_id = loc.location_id)
WHERE tea.active = 1

当我使用 EXPLAIN 时,第一个查询具有匹配所有内容的索引。当我运行第二个查询时,它缺少我的 OR 连接的连接。

为什么两个连接比使用 OR 的连接快?结果数据是一样的。

【问题讨论】:

  • 如果您同时提供了 EXPLAIN 结果,我们可以为您提供更具体的答案。

标签: mysql conditional left-join


【解决方案1】:

首先,这两个查询是不等价的。如果每个表中都有一个匹配项,则第一个将返回一行,第二个将返回两行。

不过,您的问题的答案是优化问题。 MySQL 在优化 or 条件方面做得很差。正如您所注意到的,它忽略了可以使用不同的索引来满足每个条件的事实。老实说,这是大多数数据库引擎的问题。如果您希望or 的效果具有更好的性能,那么union all 通常效果更好:

SELECT tea.*, loc.*
FROM teachers AS tea
     LEFT JOIN availability AS ava
            ON(tea.teacher_id = ava.teacher_id AND ava.end_date > 1398706428)
     LEFT JOIN locations AS loc
            ON(tea.location_id = loc.location_id)
WHERE tea.active = 1
union all
SELECT tea.*, loc.*
FROM teachers AS tea
     LEFT JOIN availability AS ava
            ON(tea.teacher_id = ava.teacher_id AND ava.end_date > 1398706428)
     LEFT JOIN locations AS loc
            ON(ava.location_id = loc.location_id)
WHERE tea.active = 1;

【讨论】:

    猜你喜欢
    • 2019-09-10
    • 2011-01-20
    • 2013-12-09
    • 2011-12-11
    • 2017-06-17
    • 2014-02-20
    • 1970-01-01
    • 1970-01-01
    • 2021-03-21
    相关资源
    最近更新 更多