多SQL查询或连接?
我有一个表SpecialOffers
并表的特别优惠项目叫做SOItems
,我希望得到一个特定项目的优惠,如果我发现它首先,我这样做:多SQL查询或连接?
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倍多,这就是为什么我问ü:)
感谢
这手优化可能是不必要的,因为优化超过能够处理这一点。
您可以将两者都放入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支票或其他任何东西 - 内部联接意味着生存的检查是多余的,因为这会不会以其他方式将任何东西。这使得代码具有更好的可维护性,因为如果它发生更改,则不需要复制该条件,并且连接中的代码不可能被意外更改。另一方面,如果加入会发生变化,则可能会产生更严重的影响。
请注意,您仍然可以在不使用EXISTS检查的情况下将其编写为WHERE版本。
较少的代码通常意味着缺少隐藏的地方。
在Management Studio的窗口中同时过去两个查询,并显示查询的执行计划。这将告诉你到底发生了什么。
您很可能会看到性能差异很小。什么可能使第二个稍微快一点是它没有IF EXISTS(...)
,但另一方面,结果将被缓存,所以差异仍然很小。
另一件可以有所作为的事情是,您正在用第一个查询将更多数据放入#SO
表中。正如您使用SELECT *
,您获得的数据比您需要的要多。例如,包含字段SOItems.SpecialOfferID
和SpecialOffers.Id
,但您知道它们始终是相同的。指定您希望返回的字段,以便您不会获取比您需要的更多的字段。
非常感谢我同意你的看法,但我不会优化,直到我遇到性能问题,我不同意,我的意思是如果你更好地编写代码,你将不会遇到性能问题,那么您不必优化 – AlaaL 2012-04-22 13:15:55
@TheDarkLord代码需要首先正确工作,可维护并满足基本的最佳实践。之后的一切都是优化。但是你说的对,经过很多(14年,也许是?)年的SQL Server之后,我对基本最佳实践的定义通常足以避免进一步的优化。 – 2012-04-22 13:26:56
感谢您的帮助。 – AlaaL 2012-04-22 13:53:09