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
答案 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)
上的索引。