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

假设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.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
条件。

第一个查询看起来会快一点,但是如果您想要真实的统计信息。。。查看探查器跟踪和执行计划