我们有一个传递控制系统,每个传递操作都存储在Event
MSSQL Server
表中。我们希望根据它们之间的关系将多个表与Event
表连接起来,如下图所示。但是,我不确定我使用的分组方法是否正确,因为查询需要花费大量时间。能否请您澄清一下如何通过多个分组加入这些表格?这是我使用的JOIN
子句:
SELECT t.CardNo, t.EventTime, t1.EmployeeName,
t1.Status, t2.EventCH, t3.DoorName, t4.JobName, t5.DeptName
FROM Event t
LEFT JOIN Employee AS t1 ON t.EmployeeID = t1.ID
LEFT JOIN EventType AS t2 ON t.EventTypeID = t2.ID
LEFT JOIN Door AS t3 ON t.DoorID = t3.ID
LEFT JOIN Job AS t4 ON t1.JobID = t4.ID
LEFT JOIN Department AS t5 ON t1.DepartmentID = t5.ID
ORDER BY t.EventID Desc
更新:发布以下执行计划:
答案 0 :(得分:1)
嘿,您是否尝试创建两个CTE来对连接进行分组?
因此,在一个CTE中为Employee,Department和Job创建一个联接。 对于其他CTE,为Event,Eventtype和Door创建一个连接。最后,使用员工ID和ID加入两个CTE。
将连接的表聚合在一起可能比一次性完成连接更快。顺便说一下,每个表的唯一约束是什么?
;WITH a AS
(
SELECT
t1.ID
,t1.EmployeeName
,t1.Status
,t4.JobName
,t5.DeptName
FROM
Employee t1
LEFT JOIN Job t4
ON t1.JobID = t4.ID
LEFT JOIN Department t5
ON t1.DepartmentID = t5.ID
)
,b AS
(
SELECT
t.EmployeeID
,t.CardNo
,t.EventTime
,t2.EventCH
,t3.DoorName
FROM
[Event] t
LEFT JOIN EventType t2
ON t.EventTypeID = t2.ID
LEFT JOIN Door t3
ON t.DoorID = t3.ID
)
SELECT
*
FROM
b
LEFT JOIN a
ON b.EmployeeID = a.ID
答案 1 :(得分:1)
您问题中的查询不代表查询计划中的查询。特别是,它具有条件
RIGHT(t.cardno, 8) = RIGHT(t1.cardno, 8)
函数的使用排除了计划索引的使用。
我的建议是为每个表添加一个虚拟列,对其进行索引,然后在连接中使用它:
alter table tEvent add cardno8 as RIGHT(cardno, 8);
alter table tEmployee add cardno8 as RIGHT(cardno, 8);
create index idx_tEvent_cardno8 tEvent(cardno8);
create index idx_tEmployee_cardno8 tEmployee(cardno8);
如果您将比较更改为:
,这应该有助于提升效果on t.cardno8 = t1.cardno8
此外,您的查询没有WHERE
子句,因此它(可能)处理了大量数据。