多SQL查询或连接?

时间:2012-04-22 13:01:12

标签: sql-server performance

我有一个表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查询或使用连接来提高性能的效率和效果更高

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

感谢

2 个答案:

答案 0 :(得分: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检查。

较少的代码通常意味着隐藏错误的地方较少。

答案 1 :(得分:1)

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

您很可能会发现性能差异非常小。什么可能使第二个更快一点,它没有IF EXISTS(...),但另一方面,结果将被缓存,所以差异仍然很小。

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