SQL查询性能

时间:2010-08-06 15:57:58

标签: tsql

我在查询中出现性能问题我需要一些提示性能的提示我尝试使用UNION ALL但只赢了一秒

取值

ELECT    GE.Id, V.Gid, V.EventOn, V.[Type], GE.SiteId, S.[$Refex] SiteRefex, V.Quantity, GE.IsIgnored
FROM         GoodsEvent GE INNER JOIN
                          (/* 2. SI que gerem Quantity  < 0*/ SELECT GE_SI_SO.Gid, GE_SI_SO.[Type], max(GE.EventOn) EventOn, GE_SI_SO.Quantity
                            FROM          GoodsEvent GE INNER JOIN
                                                       (SELECT     GGE.Gid, CASE WHEN SUM(GGE.Qtd) < 0 THEN 'SO' ELSE 'SI' END [Type], SUM(GGE.Qtd) Quantity
                                                         FROM          (SELECT     GE.Gid, CASE WHEN GE.[Type] = 'SI' THEN COUNT(GE.[Type]) ELSE 0 END nSI, 
                                                                                                        CASE WHEN GE.[Type] = 'SO' THEN COUNT(GE.[Type]) ELSE 0 END nSO, CASE WHEN GE.[Type] = 'SI' THEN SUM(GE.Quantity) 
                                                                                                        ELSE SUM(GE.Quantity) * - 1 END Qtd
                                                                                 FROM          GoodsEvent GE
                                                                                 WHERE      GE.IsDeleted = 0 AND GE.[Type] IN ('SI', 'SO')
                                                                                 GROUP BY GE.Gid, GE.[Type]) GGE
                                                         GROUP BY GGE.Gid
                                                         HAVING      SUM(GGE.nSI) > SUM(GGE.nSO) + 1 OR
                                                                                SUM(GGE.Qtd) < 0) GE_SI_SO ON GE.Gid = GE_SI_SO.Gid AND GE.[Type] = GE_SI_SO.[Type]
                            WHERE      GE.IsDeleted = 0
                            GROUP BY GE_SI_SO.Gid, GE_SI_SO.Quantity, GE_SI_SO.[Type]
                            UNION 
                            /* 1. Vários SI c/ ou s/ LO no meio*/ SELECT GE_BASE.Gid, 'SI' AS [Type], GE_Base.EventOn, 0 AS Quantity
                            FROM         (SELECT     ROW_NUMBER() OVER (ORDER BY GE.Gid, GE.EventOn) RowNumber, GE.Gid, GE.[Type], GE.EventOn
                            FROM         GoodsEvent GE
                            WHERE     GE.IsDeleted = 0) GE_BASE INNER JOIN
                          (SELECT     ROW_NUMBER() OVER (ORDER BY GE.Gid, GE.EventOn) RowNumber, GE.Gid, GE.[Type]
FROM         GoodsEvent GE
WHERE     GE.IsDeleted = 0) GE_O ON GE_BASE.Gid = GE_O.Gid AND 
GE_O.RowNumber = CASE GE_BASE.RowNumber WHEN 1 THEN 1 ELSE GE_BASE.RowNumber - 1 END
WHERE     GE_BASE.RowNumber <> GE_O.RowNumber AND GE_BASE.[Type] = GE_O.[Type] AND GE_BASE.[Type] = 'SI' AND GE_O.[Type] = 'SI'
UNION
/* 3. LO sem SI a preceder*/ SELECT GE.Gid, 'LO' [Type], GE.EventOn, 0 Quantity
FROM         GoodsEvent GE INNER JOIN
                          (SELECT     GE.Gid, MIN(GE.EventOn) EventOn
                            FROM          GoodsEvent GE
                            WHERE      GE.IsDeleted = 0
                            GROUP BY GE.Gid) GGE ON GE.Gid = GGE.Gid AND GE.EventOn = GGE.EventOn
/*WHERE     GE.[Type] = 'LO' AND GE.IsDeleted = 0*/ WHERE GE.[Type] <> 'SI' AND GE.IsDeleted = 0
UNION 
/*4. IG  Gids com Eventos de 'SI' Apos fecho de SiteIn */ SELECT GE.Gid, 'IG' [Type], GE.EventOn, 0 Quantity
FROM         GoodsEvent GE INNER JOIN
                          (SELECT     Gid, MIN(EventOn) AS EventOn
                            FROM          GoodsEvent AS GE
                            WHERE      GE.IsDeleted = 0
                            GROUP BY Gid) GGE ON GE.Gid = GGE.Gid AND GGE.EventOn = Ge.EventOn INNER JOIN
                      Goods G ON G.Gid = Ge.Gid INNER JOIN
                      SiteIn SI ON G.SiteIn = SI.[$Id] AND SI.Closed = 1 AND SI.ClosedOn < GE.EventOn
WHERE     GE.IsDeleted = 0) V ON GE.Gid = V.Gid AND GE.EventOn = V.EventOn AND GE.IsDeleted = 0 INNER JOIN
[Site] S ON S.[$Id] = GE.SiteId

2 个答案:

答案 0 :(得分:1)

在运行SQL Server探查器时执行它。然后保存输出,并将其插入数据库引擎优化顾问。这将为您提供索引和统计数据的想法

答案 1 :(得分:0)

在不知道详细信息(表的大小,索引,主键,......)的情况下调整查询并不简单。

但是看看你的查询,这太复杂了。你应该从头开始我猜。但是这里有一些可以帮助你的提示:

  • 您有许多子查询并加入查询,但您只使用一个名为GoodsEvent的表。想想看,你真的需要那些连接和子查询吗?如果您认为自己需要,请尝试将结果放在临时表中并与临时表连接。您可以在查询的其他部分重用该临时表

  • 第3部分&amp;您的查询中的4个:您使用表GoodEvents进行内部联接,您在其中计算min EventOn,但是您从不在主查询中使用此结果。因此,使用子查询似乎没有用处

  • 尝试为您的表找到不同的联盟,命名所有这些同样使其变得复杂

  • 您在查询中使用表格GGE。此GGE表在查询的第一部分中生成,但您可以在第3部分和第3部分中重复使用它。 4,重新考虑一下。你不能把它放在临时表中吗?

我希望这些技巧可以帮到你一点点,但如前所述,没有更多细节,几乎不可能重新编写这个查询。也许您可以发布您的查询执行计划?

或者,如果您发送给我,您创建了goodsEvent表的脚本和您想要的结果,那么我可以尝试编写它。

问候 人