多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版本。

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

+0

非常感谢我同意你的看法,但我不会优化,直到我遇到性能问题,我不同意,我的意思是如果你更好地编写代码,你将不会遇到性能问题,那么您不必优化 – AlaaL 2012-04-22 13:15:55

+0

@TheDarkLord代码需要首先正确工作,可维护并满足基本的最佳实践。之后的一切都是优化。但是你说的对,经过很多(14年,也许是?)年的SQL Server之后,我对基本最佳实践的定义通常足以避免进一步的优化。 – 2012-04-22 13:26:56

+0

感谢您的帮助。 – AlaaL 2012-04-22 13:53:09

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

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

另一件可以有所作为的事情是,您正在用第一个查询将更多数据放入#SO表中。正如您使用SELECT *,您获得的数据比您需要的要多。例如,包含字段SOItems.SpecialOfferIDSpecialOffers.Id,但您知道它们始终是相同的。指定您希望返回的字段,以便您不会获取比您需要的更多的字段。

+0

是的,谢谢,实际上我并没有在真实的代码中使用SELECT *,而是在这里写下来,所以我不必写下字段的名字:) – AlaaL 2012-04-22 13:19:21

+0

@TheDarkLord:很高兴听到。 :) – Guffa 2012-04-22 13:21:04