SQL 缓慢的嵌套查询
我有一张名为 Staff 的表和一张名为 Supervisors 的表。
员工有 StaffID
、FirstName
、LastName
等。
主管包含 RelationshipID
、StaffID、
SupervisorID
、SetBy
、SetOn
、状态
。
基本上,主管表为我们提供了员工自我关系的审计跟踪。我们有一个员工表,还有一个员工:员工关系(主管:员工)表,其中包含一些额外信息(过时的、当前的、不正确的)以及设置它的人员和设置时间的 StaffID。
现在,我正在编写一个查询来查找所有孤儿员工。我有:(
SELECT *
FROM Staff
WHERE StaffID NOT IN (SELECT StaffID
FROM Supervisors
WHERE Status = 0
OR Status = 2);
状态 0 是来自公司数据库的初始加载,2 是已验证的修改记录。所有其他都是“过时”、“不正确”等...)
问题是我有超过 6000 名员工和超过 5000 名员工:supervisor 关系,这基本上是一个 NxM 查询,意味着 MySQL 必须筛选 300 万种排列。
我不是 SQL 忍者,有更好的方法吗?
(注意,我根本不希望经常运行这个特定的查询)
I have a table called Staff and a table called Supervisors.
Staff has StaffID
, FirstName
, LastName
, etc...
Supervisors contains RelationshipID
, StaffID
, SupervisorID
, SetBy
, SetOn
, Status
.
Basically, the Supervisors tables gives us an audit trail for the Staff self-relationship. We have a table of Staff, and we have a table of Staff:Staff relationships (supervisor:staff) with some extra information (obsolete, current, incorrect) and a StaffID who set it and when they set it.
Now, I'm writing a query to find all orphaned staff members. I have:
SELECT *
FROM Staff
WHERE StaffID NOT IN (SELECT StaffID
FROM Supervisors
WHERE Status = 0
OR Status = 2);
(status 0 is initial load from corporate DB and 2 is modified record which has been verified. All others are 'obsolete', 'incorrect', etc...)
The issue is I have over 6000 staff and over 5000 staff:supervisor relationships and this is basically an NxM query meaning MySQL has to sift through 3 million permutations.
I'm not an SQL ninja, is there a better way to do this?
(Note, I do not expect to be running this particular query very often at all)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
假设
SUPERVISOR.staffid
和SUPERVISOR.status
列不可为空,请使用:否则,
NOT IN
/NOT EXISTS
是等价的 &如果列可为空,则性能会更好。欲了解更多信息:
Assuming
SUPERVISOR.staffid
andSUPERVISOR.status
columns are not nullable, use:Otherwise,
NOT IN
/NOT EXISTS
are equivalent & perform better if the columns are nullable.For more info:
作为联接而不是 NOT IN 会更好地执行:
以下是我对其进行转换的方法:
通过应用布尔定律相当于
(假设 Status 永远不会为 NULL),并且从那里只是一个联接。
This would be better performed as a join rather than a NOT IN:
Here's how I transformed it:
by applying Boole's law is equivalent to
(assuming Status can never be NULL) and from there is just a join.