如何重写ON子句以避免使用OR

问题描述 投票:0回答:1

由于使用OR作为ONJOIN语句的一部分,因此查询效率非常低。

    SELECT COUNT(*)
    FROM Meetings
    LEFT JOIN Users
         ON (Meetings.AdministratorID = Users.UserID
             OR Meetings.ChairpersonID = Users.UserID);

(请注意,字段列表实际上包含一堆字段,但出于本示例的目的,我已将其简化为仅行计数。)

这实际上是较大的联接中的子查询,该联接将会议加入组织。如果有主席,则应使用主席的组织。否则,应使用管理员的组织。这两个字段中的一个或两个都将被填写,并且字段列表确保在查询结果中输出正确的值。

使用EXPLAIN,我可以看到OR运算符意味着无法使用索引,并且所有行组合都需要单独检查。约有10万个会议记录和约7万个用户记录,这是一个巨大的查询性能问题,因为这意味着需要检查约70亿个组合。

删除表达式的OR Meetings.ChairpersonID = Users.UserID部分会产生即时结果,因为查询可以正确使用索引,但显然不能提供我们需要的结果。

任何人都可以建议一种重写此查询的方式以避免性能问题?

我正在使用MySQL 5。

mysql sql sqlperformance
1个回答
0
投票

尝试使用exists

SELECT COUNT(*)
FROM Meetings m
WHERE EXISTS (SELECT 1
              FROM Users u
              WHERE u.UserID = m.AdministratorID
             ) OR
      EXISTS (SELECT 1
              FROM Users u
              WHERE u.UserID = m.ChairpersonID
             );

这可以利用Users(UserId)上的索引-如果UserId是主键,该索引将自动存在。

注意:我认为这可以通过计算会议来完成您想要的工作。您的版本吸引了用户。因此,如果主席和管理员都在给定会议的Users中,则该会议将计为2个用户,而不是1个会议。

© www.soinside.com 2019 - 2024. All rights reserved.