JOIN 中的 Case 语句会降低查询的性能

时间:2021-06-30 14:12:15

标签: sql sql-server

JOIN 中的Case 语句降低了查询的性能,有什么办法可以提高查询性能吗

SELECT  A.TestColumn
FROM A with(nolock) 
INNER JOIN B with(nolock) 
  ON A.ID = B.ID  
  and A.InvoiceNo = CASE WHEN B.InvoiceType=2 
                    THEN B.MainInvoiceNo 
                    ELSE B.InvoiceNo END

4 个答案:

答案 0 :(得分:1)

试试:

1) 使用有价值的 CASE

SELECT A.TestColumn
FROM   A
       INNER JOIN B
           ON A.ID = B.ID  and  
           A.InvoiceNo = CASE B.InvoiceType 
                            WHEN 2 THEN B.MainInvoiceNo 
                            ELSE B.InvoiceNo 
                         END

2) 使用 UNION ALL

SELECT A.TestColumn
FROM   A
       INNER JOIN B
           ON A.ID = B.ID  and  
           A.InvoiceNo = B.MainInvoiceNo 
WHERE  B.InvoiceType=2
UNION ALL
SELECT A.TestColumn
FROM   A
       INNER JOIN B
           ON A.ID = B.ID  and  
           A.InvoiceNo = B.InvoiceNo
WHERE  B.InvoiceType<>2

答案 1 :(得分:0)

可能使用联合会是最好的表现:

SELECT  A.TestColumn
FROM A 
INNER JOIN B 
  ON A.ID = B.ID  
  and B.InvoiceType=2 
  and A.InvoiceNo = B.MainInvoiceNo 
union all 
SELECT  A.TestColumn
FROM A with(nolock) 
INNER JOIN B with(nolock) 
  ON A.ID = B.ID  
  and B.InvoiceType <> 2
  and A.InvoiceNo =  B.InvoiceNo

但您也可以尝试使用 OR :

SELECT  A.TestColumn
FROM A with(nolock) 
INNER JOIN B with(nolock) 
  ON A.ID = B.ID  
  and 
   ( 
   (B.InvoiceType= 2  and A.InvoiceNo = B.MainInvoiceNo)
   or 
   (B.InvoiceType<> 2  and A.InvoiceNo = B.InvoiceNo)   
   )   

答案 2 :(得分:0)

使用 case expression 作为连接条件的一部分将强制 SQL Server 扫描您的索引(如果 id 是聚集索引,则可能是表扫描)。< /p>

根据数据的基数和每个连接条件的预期行数,使用两个单独的查询结果 unioned 可以产生更好的性能。

这是因为对于每个单独的查询,优化器可能会使用索引搜索,从而导致总体上很少logical reads

此外,由于您仅从 A 返回数据,因此您可以尝试使用 exists

Select A.TestColumn
from A
where exists (
  select * from B where B.Id = A.Id and B.InvoiceType=2 and A.InvoiceNo=B.MainInvoiceNo
)
or exists (
  select * from B where B.Id=A.Id and B.InvoiceNo = A.InvoiceNo 
)

答案 3 :(得分:0)

我建议两个 LEFT JOIN 和一个 WHERE

SELECT A.TestColumn
FROM A LEFT JOIN
     B B1
     ON A.ID = B1.ID AND
        B1.InvoiceType = 2
        A.InvoiceNo = B.MainInvoiceNo LEFT JOIN
     B B2
     ON A.ID = B2.ID AND
        A.InvoiceNo = B2.InvoiceNo 
WHERE B1.ID IS NOT NULL OR B2.ID IS NOT NULL;

SQL Server 应该会发现实施高效的执行计划要容易得多。我会推荐 B(ID, MainInvoiceNo, InvoiceType)B(ID, InvoiceNo) 上的索引。