Sql-Server
條件連接 - 特定列選擇
我有這樣的表:
Table Employee ( Emp_Id, Full_Name, ...) Table Order ( Submitter_Id, Recipient_Id, ...)
然後說我有這樣的條件加入:
select isnull(Emp.Full_Name, Emp2.Full_name) as Recipient -- , other fields from Order left outer join Employee Emp on Emp.Emp_Id = Order.Recipient_Id left outer join Employee Emp2 on Emp2.Emp_Id = Order.Submitter_Id -- where clauses
**簡要說明:**查詢將返回特定訂單的收件人姓名。訂單可能設置了收件人 ID,如果未設置收件人,則使用送出者 ID。
**條件:**表
Order
和Employee
內部都有大量記錄,因此將它們連接起來是一項昂貴的操作。80% - 90% 的記錄Order
已經recipient_id
設置,所以加入submitter_id
是無用的操作。使用 isnull 作為連接條件會導致index scan
(根據我的經驗)。使用subquery
for column 可能會有所幫助,但成本可能很高,因為操作可以逐行進行。像這樣的情況有條件加入嗎?
關於您對掃描的評論,這是因為在連接中使用 ISNULL() 會操縱該欄位,因此它不再是 SARGable。將其拆分可能會更快,而不是嘗試在單個查詢中完成所有工作。例如:
DECLARE @Recipient_ID INT, @Submitter_ID INT SELECT @Recipient_ID = Order.Recipient_Id, @Submitter_ID = Order.Submitter_Id FROM Order -- where clauses IF @Recipient_ID IS NULL SELECT Emp.Full_Name FROM Employee Emp WHERE Emp.Emp_Id = @Submitter_ID ELSE SELECT Emp.Full_Name FROM Employee Emp WHERE Emp.Emp_Id = @Recipient_ID
根據評論編輯:既然可以有很多訂單,那這個呢?它是 SARGable,所以應該很好地索引,並且您不會多次查詢該表。
with cte as ( SELECT COALESCE(Order.Recipient_Id, Order.Submitter_Id) AS EmployeeID FROM Order -- where clauses ) SELECT Emp.Full_Name FROM Employee Emp INNER JOIN cte on cte.EmployeID = Emp.Emp_Id