-1

我有一张SpecialOffers名为特价商品的桌子和桌子,SOItems 如果我找到它,我想获得特定商品的特价,所以首先我这样做了:

IF EXISTS(SELECT * FROM SOTtems WHERE ItemType = 2 AND Itemid = @id)
BEGIN
      INSERT INTO #SO
      SELECT * FROM SpecialOffers so 
      INNER JOIN SOItems soi ON so.Id = soi.SpecialOfferID
      WHERE soi.ItemType = 2 AND soi.Itemid = @id
END

但是为了摆脱 INNER JOIN 因为我认为这对性能更好,我这样做了:

DECLARE @specialOfferID INT

SET @specialOfferID = (SELECT SpecialOfferID FROM SOTtems WHERE ItemType = 2 AND Itemid = @id)

IF @specialOfferID IS NOT NULL
BEGIN
     INSERT INTO #SO
     SELECT * FROM SpecialOffers so 
     WHERE ID = @specialOfferID
END

因此,对于这个示例和一般情况,执行更多 sql 查询或使用 join 哪个更有效,性能更好

注意:在我写的存储过程中,我必须这样做超过 6 次,这就是我问你的原因 :)

谢谢

4

2 回答 2

1

这种手动优化可能是不必要的,因为优化器完全有能力处理这个问题。

您可以将两者放入 SSMS 并一起运行,并查看执行计划中的相对成本。

避免连接通常不是优化的第一步。

我的第一步通常是查看索引策略并确保我没有遗漏基本索引,然后查看执行计划,看看是否有任何明显的问题。

然后我不会优化,直到我遇到实际的性能问题 - 然后只有在了解真正导致性能问题的原因之后。

我实际上会将其简化为:

INSERT INTO #SO
SELECT *
FROM SpecialOffers so 
INNER JOIN SOItems soi
    ON so.Id = soi.SpecialOfferID
    AND soi.ItemType = 2
    AND soi.Itemid = @id

就是这样 - 没有 EXISTS 检查或其他任何东西 - 内部连接意味着检查是否存在是多余的,因为否则它不会插入任何东西。从某种意义上说,这使得代码更易于维护,因为如果条件发生更改,您不需要复制条件,并且连接中的代码不太可能被意外更改。另一方面,如果连接确实被更改,它可能会产生更严重的影响。

请注意,您仍然可以将其编写为 WHERE 版本,而无需使用 EXISTS 检查。

更少的代码通常意味着更少的错误隐藏位置。

于 2012-04-22T13:10:05.580 回答
1

在 Management Studio 的窗口中粘贴这两个查询,并显示查询的执行计划。这会告诉你到底发生了什么。

您很可能会看到性能差异很小。可能使第二个更快的是它没有IF EXISTS(...),但另一方面,结果将被缓存,因此差异仍然很小。

另一件可以产生影响的事情是,您正在#SO使用第一个查询将更多数据放入表中。当您使用SELECT *时,您获得的数据超出了您的需要。例如,字段SOItems.SpecialOfferIDSpecialOffers.Id都包含在内,但您知道它们始终相同。指定您想要返回的字段,这样您就不会获取超出您需要的信息。

于 2012-04-22T13:12:00.863 回答