我有一个表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次,这就是我问你的原因:)
感谢
答案 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.SpecialOfferID
和SpecialOffers.Id
都包含在内,但您知道它们始终相同。指定要返回的字段,这样就不会获取超出需要的字段。