производительность SQL-запросов - PullRequest
0 голосов
/ 06 августа 2010

У меня проблема с производительностью в моем запросе. Мне нужны советы по повышению производительности, которые я пробовал с UNION ALL, но выиграл только одну секунду

S

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 ]

1 голос
/ 06 августа 2010

Запустите его, пока вы используете профилировщик SQL Server.Затем сохраните вывод и вставьте его в помощник по настройке ядра СУБД.Это даст вам идеи для индексов и статистики

0 голосов
/ 07 августа 2010

Это не просто настроить запрос, не зная деталей (размер вашей таблицы, индексы, первичный ключ, ...).

Но, глядя на ваш запрос, он слишком сложен. Вы должны просто начать с нуля, я думаю. Но вот несколько советов, которые могут вам помочь:

  • у вас есть много подзапросов и вы включаете в свой запрос, но вы используете только одну таблицу под названием GoodsEvent. Подумайте, вам действительно нужны эти соединения и подзапросы? Если вы считаете, что вам нужно, попробуйте поместить результат во временную таблицу и соединитесь с временной таблицей. Вы можете повторно использовать эту временную таблицу в других частях вашего запроса

  • часть 3 и 4 вашего запроса: вы выполняете внутреннее соединение с таблицей GoodEvents, где вычисляете min EventOn, но никогда не используете этот результат в основном запросе. Таким образом, использование подзапроса кажется бесполезным

  • Попытайтесь найти различные псевдонимы для ваших таблиц, если назвать их одинаково, это усложнит

  • вы используете таблицу GGE на протяжении всего вашего запроса. Эта таблица GGE создана в первой части запроса, но вы повторно используете ее в частях 3 и 4, переосмыслите это. Не можете ли вы положить его во временную таблицу?

Я надеюсь, что эти советы помогут вам немного, но, как уже было сказано, без дополнительных деталей практически невозможно переделать этот запрос. Может быть, вы можете опубликовать план выполнения запроса?

Или, если вы отправите мне скрипт создания таблицы goodsEvent и нужного вам результата, возможно, я попытаюсь написать его.

С уважением парень

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...