SQL联接和排除
假设T-SQL中的查询也是这样SQL联接和排除,sql,sql-server,performance,tsql,Sql,Sql Server,Performance,Tsql,假设T-SQL中的查询也是这样 SELECT * FROM Stock S LEFT JOIN StockBarcode SB ON SB.StockID = S.StockID AND SB.ShopID = @ShopID AND SB.Inactive = 0 LEFT JOIN StockBarcode SB1 ON SB1.StockID = S.S
SELECT *
FROM Stock S
LEFT JOIN StockBarcode SB ON SB.StockID = S.StockID
AND SB.ShopID = @ShopID
AND SB.Inactive = 0
LEFT JOIN StockBarcode SB1 ON SB1.StockID = S.StockID
AND SB1.ShopID = 0
AND SB1.Inactive = 0
WHERE S.StockID = @StockID
我的理解是,我可以重写查询本身
SELECT *
FROM Stock S
LEFT JOIN StockBarcode SB ON S.StockID = SB.StockID
AND SB.ShopID = @ShopID
LEFT JOIN StockBarcode SB1 ON S.StockID = SB1.StockID
AND SB1.ShopID = 0
WHERE S.StockID = @StockID
AND ISNULL(SB.Inactive, 0) = 0
AND ISNULL(SB1.Inactive, 0) = 0
…结果是一样的。(如果我错了,请纠正我)
哪个是最佳查询?为什么?如果我使用另一个数据库引擎,比如MySql,情况会有所不同吗
提前感谢您的回答:-)
编辑:
为了澄清,这里是目前的整个问题,如果这有帮助的话
SELECT
SSCLRU.SupplierCode,
S.[Description],
S.TaxRate AS GSTRate,
ISNULL(ISNULL(SB.PackPrice, SB1.PackPrice), S.RRP) AS Price,
ISNULL(SB.PackSize, SB1.PackSize) AS Quantity,
ISNULL(SB.SalePrice, SB1.SalePrice) AS SalePrice,
ISNULL(SB.SaleDateFrom, SB1.SaleDateFrom) AS SalePriceStartDate,
ISNULL(SB.SaleDateTo, SB1.SaleDateTo) AS SalePriceEndDate
FROM Stock S
LEFT JOIN StockSupplierCodePreferredLastReceivedUnique SSCLRU ON
S.StockID = SSCLRU.StockID
LEFT JOIN StockBarcode SB ON
S.StockID = SB.StockID AND
SB.ShopID = @ShopID AND
SB.Inactive = 0
LEFT JOIN StockBarcode SB1 ON
S.StockID = SB1.StockID AND
SB1.ShopID = 0 AND
SB1.Inactive = 0
WHERE S.StockID = @StockID
哪个是最佳查询?为什么
查看查询计划
但我打赌第一个应该更有效,因为索引可以覆盖SB.Inactive=0
条件
如果我使用另一个数据库引擎,比如MySql,情况会有所不同吗
当然,执行计划和性能严格取决于供应商。第一个更清楚,因为您不必担心WHERE中不匹配的行 然而,我可能会使用这个构造来完全分离连接和过滤条件
FROM
Stock S
LEFT JOIN
StockSupplierCodePreferredLastReceivedUnique SSCLRU ON S.StockID = SSCLRU.StockID
LEFT JOIN
(
SELECT StockID, ...
FROM StockBarcode
WHERE ShopID = @ShopID AND Inactive = 0
) SB ON S.StockID = SB.StockID
LEFT JOIN
(
SELECT StockID, ...
FROM StockBarcode
WHERE ShopID = 0 AND Inactive = 0
) SB1 ON S.StockID = SB1.StockID
WHERE
S.StockID = @StockID
派生表也可以推送到CTE(或2)中。它们不完全相同,除非StockBarcode.Inactive不可为空
如果StockBarcode.Inactive可为空,则第一次查询将不会返回Inactive为空的StockBarcode的任何详细信息(因为它们未通过联接条件),而第二个查询将包括它们,如果它们匹配其他连接条件-它们将匹配
where
条件。第一个查询看起来会快一点,但是如果您想要真实的统计信息。。。查看探查器跟踪和执行计划