Sql-Server

條件連接 - 特定列選擇

  • January 5, 2019

我有這樣的表:

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。

**條件:**表OrderEmployee內部都有大量記錄,因此將它們連接起來是一項昂貴的操作。80% - 90% 的記錄Order已經recipient_id設置,所以加入submitter_id是無用的操作。使用 isnull 作為連接條件會導致index scan(根據我的經驗)。使用subqueryfor 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

引用自:https://dba.stackexchange.com/questions/51456