SQL 缓慢的嵌套查询

发布于 2024-11-26 10:57:00 字数 846 浏览 2 评论 0原文

我有一张名为 Staff 的表和一张名为 Supervisors 的表。

员工有 StaffIDFirstNameLastName 等。

主管包含 RelationshipIDStaffID、SupervisorIDSetBySetOn状态

基本上,主管表为我们提供了员工自我关系的审计跟踪。我们有一个员工表,还有一个员工:员工关系(主管:员工)表,其中包含一些额外信息(过时的、当前的、不正确的)以及设置它的人员和设置时间的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

日裸衫吸 2024-12-03 10:57:00

假设 SUPERVISOR.staffidSUPERVISOR.status不可为空,请使用:

   SELECT st.*
     FROM STAFF st
LEFT JOIN SUPERVISOR s ON s.staffid = st.staffid
                      AND s.status NOT IN (0,2)
    WHERE s.staffid IS NULL

否则,NOT IN/NOT EXISTS 是等价的 &如果列可为空,则性能会更好。

欲了解更多信息:

Assuming SUPERVISOR.staffid and SUPERVISOR.status columns are not nullable, use:

   SELECT st.*
     FROM STAFF st
LEFT JOIN SUPERVISOR s ON s.staffid = st.staffid
                      AND s.status NOT IN (0,2)
    WHERE s.staffid IS NULL

Otherwise, NOT IN/NOT EXISTS are equivalent & perform better if the columns are nullable.

For more info:

如痴如狂 2024-12-03 10:57:00

作为联接而不是 NOT IN 会更好地执行:

SELECT st.* 
FROM Staff st
LEFT JOIN Supervisors su ON st.StaffID = su.StaffID 
          AND (su.Status <> 0 AND su.Status <> 2)
WHERE su.StaffId IS NULL

以下是我对其进行转换的方法:

NOT IN (SELECT StaffID FROM Supervisors WHERE Status = 0 OR Status = 2)

通过应用布尔定律相当于

IN (SELECT StaffID FROM Supervisors WHERE Status <> 0 AND Status <> 2);

(假设 Status 永远不会为 NULL),并且从那里只是一个联接。

This would be better performed as a join rather than a NOT IN:

SELECT st.* 
FROM Staff st
LEFT JOIN Supervisors su ON st.StaffID = su.StaffID 
          AND (su.Status <> 0 AND su.Status <> 2)
WHERE su.StaffId IS NULL

Here's how I transformed it:

NOT IN (SELECT StaffID FROM Supervisors WHERE Status = 0 OR Status = 2)

by applying Boole's law is equivalent to

IN (SELECT StaffID FROM Supervisors WHERE Status <> 0 AND Status <> 2);

(assuming Status can never be NULL) and from there is just a join.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文