在SQL中哪个更喜欢IN vs Join vs Equals?

时间:2014-06-09 07:14:52

标签: sql sql-server query-performance

我想从tbl_Manufacturer获得制造商。我写了三个不同的查询来从tbl_Sales_OrderItems表中获取项目的制造商。我想知道哪一个更喜欢。有人会告诉我哪个查询应该用于其他查询以及为什么?

查询1:使用子查询

SELECT manufacturer
FROM   tbl_Manufacturers
WHERE  ManufacturerID IN(SELECT trc.ManufacturerID
                         FROM   tbl_Sales_RepairCategory trc
                         WHERE  trc.RepairCategoryID IN (SELECT RepairCategoryID
                                                         FROM   tbl_VendorParts
                                                         WHERE  VendorPartID IN (SELECT refid
                                                                                 FROM   tbl_Sales_OrderItems
                                                                                 WHERE  typeid = 2
                                                                                        AND SalesOrderID = 182)))

查询2:使用不同的子查询

SELECT DISTINCT Manufacturer
FROM   tbl_Manufacturers m,
       tbl_VendorParts tvp,
       tbl_Sales_RepairCategory trc
WHERE  tvp.RepairCategoryID = trc.RepairCategoryID
       AND trc.ManufacturerID = m.ManufacturerID
       AND tvp.VendorPartID IN (SELECT Refid
                                FROM   tbl_Sales_OrderItems
                                WHERE  isnull(typeid, 0) = 2
                                       AND SalesOrderID = 182)

查询3:使用'='(等于)与Distinct,加入

SELECT DISTINCT Manufacturer
FROM   tbl_Manufacturers m,
       tbl_VendorParts tvp,
       tbl_Sales_RepairCategory trc
WHERE  tvp.RepairCategoryID = trc.RepairCategoryID
       AND trc.ManufacturerID = m.ManufacturerID
       AND tvp.VendorPartID = (SELECT Refid
                               FROM   tbl_Sales_OrderItems
                               WHERE  isnull(typeid, 0) = 2
                                      AND SalesOrderID = 182) 

这是执行计划enter image description here

请建议使用哪个?

建议赞赏!

2 个答案:

答案 0 :(得分:1)

  • general 中,IN ==表现不佳。
  • general 中,加入是最佳选择。
  • 在where子句中具有连接条件的Pre-SQL92(旧式)连接应使用“new”(20岁以上)join语法进行编码

您提出的任何查询都不会表现得如此:

SELECT DISTINCT Manufacturer
FROM tbl_Sales_OrderItems s
JOIN tbl_VendorParts tvp ON tvp.VendorPartID = s.Refid
JOIN tbl_Sales_RepairCategory trc ON tvp.RepairCategoryID = trc.RepairCategoryID
JOIN tbl_Manufacturers m ON trc.ManufacturerID = m.ManufacturerID
WHERE (typeid = 2 OR typeid IS NULL)
AND SalesOrderID = 182

注意:

  • 所有联接都已转换为正确的联接
  • 表连接顺序已经颠倒,因此where子句在列出的第一个表上运行,因此可以最有效地使用索引,重要的是尽可能少的行访问操作
  • typeid条件已转换为OR以避免调用isnull()函数

答案 1 :(得分:0)

我喜欢在这种情况下使用exists。您知道需要检查特定表列中的信息,但不需要从这些表中返回任何信息。这正是存在的目的。存在往往比额外连接更优化。使用存在的另一个好处是你保持代码更清洁。您可以更轻松地查看从哪个表中提取必要信息,以便将来更容易维护。我建议使用这样的东西:

SELECT manufacturer
FROM   tbl_Manufacturers m
WHERE  exists   (SELECT 1
                FROM    tbl_Sales_RepairCategory trc
                join    tbl_VendorParts r
                On      trc.RepairCategoryID = r.RepairCategoryID
                join    tbl_Sales_OrderItems s
                On      s.refid = r.VendorPartID
                Where   m.ManufacturerID  = trc.ManufacturerID
                and     r.typeid = 2
                and     r.salesOrderId = 182)