由于使用OR
作为ON
中JOIN
语句的一部分,因此查询效率非常低。
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。
尝试使用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个会议。