我有四个表,即TopLevelParent,两个中级表MidParentA和MidParentB,以及一个子表,该表可以具有MidParentA或MidParentB的父级(一个或另一个midParent必须存在)。两个中级表都有一个父表TopLevelParent。
顶层表如下所示:
TopLevelId | Name -------------------------- 1 | name1 2 | name2
MidParent表如下所示:
MidParentAId | TopLevelParentId | MidParentBId | TopLevelParentId | ------------------------------------ ------------------------------------ 1 | 1 | 1 | 1 | 2 | 1 | 2 | 1 |
子表如下所示:
ChildId | MidParentAId | MidParentBId -------------------------------- 1 | 1 | NULL 2 | NULL | 2
我在较大的存储过程中使用了以下左连接,该存储过程正在超时,并且看起来最后一个左连接上的OR运算符是罪魁祸首:
SELECT * FROM TopLevelParent tlp LEFT JOIN MidParentA a ON tlp.TopLevelPatientId = a.TopLevelPatientId LEFT JOIN MidParentB a ON tlp.TopLevelPatientId = b.TopLevelPatientId LEFT JOIN Child c ON c.ParentAId = a.ParentAId OR c.ParentBId = b.ParentBId
是否有更高效的方法来进行此加入?
这是我最后所做的,这使执行时间从52秒减少到4秒。
SELECT * FROM ( SELECT tpl.*, a.MidParentAId as 'MidParentId', 1 as 'IsMidParentA' FROM TopLevelParent tpl INNER JOIN MidParentA a ON a.TopLevelParentId = tpl.TopLevelParentID UNION SELECT tpl.*, b.MidParentBId as 'MidParentId', 0 as 'IsMidParentA' FROM TopLevelParent tpl INNER JOIN MidParentB b ON b.TopLevelParentId = tpl.TopLevelParentID UNION SELECT tpl.*, 0 as 'MidParentId', 0 as 'IsMidParentA' FROM TopLevelParent tpl WHERE tpl.TopLevelParentID NOT IN ( SELECT pa.TopLevelParentID FROM TopLevelParent tpl INNER JOIN MidParentA a ON a.TopLevelParentId = tpl.TopLevelParentID UNION SELECT pa.TopLevelParentID FROM TopLevelParent tpl INNER JOIN MidParentB b ON h.TopLevelParentId = tpl.TopLevelParentID ) ) tpl LEFT JOIN MidParentA a ON a.TopLevelParentId = tpl.TopLevelParentID LEFT JOIN MidParentB b ON b.TopLevelParentId = tpl.TopLevelParentID LEFT JOIN ( SELECT [ChildId] ,[MidParentAId] as 'MidParentId' ,1 as 'IsMidParentA' FROM Child c WHERE c.MidParentAId IS NOT NULL UNION SELECT [ChildId] ,[MidParentBId] as 'MidParentId' ,0 as 'IsMidParentA' FROM Child c WHERE c.MidParentBId IS NOT NULL ) AS c ON c.MidParentId = tpl.MidParentId AND c.IsMidParentA = tpl.IsMidParentA
这消除了正在发生的表扫描,因为我已经将顶级记录与它的中级父级(如果存在)进行了匹配,并将其标记在该记录上。
我也对子记录进行了相同的操作,这意味着我可以将子记录加入MidParentId的顶级记录中,并使用IsMidParentA位标志来区分存在两个相同的MidParentId的位置(例如,ID为1 IsMidParentA和IsMidParentB)。
感谢所有花时间回答的人。