2017-01-02 3 views
0

У меня есть следующий вид: Итак, вопрос в том, как улучшить читаемость SQL этого запроса?Как улучшить читаемость и производительность SQL?

SELECT t1.Id , 
      t1.HeaderRef , 
      t1.PartRef , 
      t1.SLRef , 
      t1.DL , 
      t1.DL2 , 
      t1.DL3 , 
      t1.DL4 , 
      t1.DL5 , 
      t1.DL6 , 
      t1.DL7 , 
      t1.ItemRef , 
      t1.CalItemRef , 
      t1.RowNum , 
      t1.UnitType , 
      t1.UnitTypeTitle , 
      t1.UnitRef , 
      t1.Ratio , 
      t1.Value , 
      t1.MasterValue , 
      t1.ItemDate , 
      t1.Descript , 
      t1.Year , 
      t1.BranchRef , 
      t1.StockRef , 
      t1.OpositStockRef , 
      t1.DocTypeRef , 
      t1.BaseDocTypeRef , 
      t1.Creator , 
      t1.Confirmer , 
      t1.Num , 
      t1.State , 
      t1.DocDate , 
      t1.FCRef , 
      t1.FCTitle , 
      t1.PartTitle , 
      t1.PartCode , 
      t1.SLCode , 
      t1.DL1Code , 
      t1.DL2Code , 
      t1.DL3Code , 
      t1.DL4Code , 
      t1.DL5Code , 
      t1.DL6Code , 
      t1.DL7Code , 
      t1.UnitTitle , 
      t1.PartUnitTitle , 
      ((AVG(t1.RealPrice) + SUM(t1.CorrectPrice))/t1.Value) AS CorrectRate , 
      AVG(t1.RealPrice) + SUM(t1.CorrectPrice) AS CorrectPrice , 
      MAX(t1.CorrectAccDocHeaderRef) AS CorrectAccDocHeaderRef , 
      1 AS CorrectCreator , 
      1 AS CorrectConfirmer , 
      MAX(t1.CorrectCreateDate) AS CorrectCreateDate , 
      GETDATE() AS CorrectConfirmDate , 
      CorrectFCRate = (SELECT MAX(rr.FCRate) 
           FROM  Stc.StcDocRate AS rr 
           WHERE  rr.ItemRef = t1.Id 
             AND rr.PriceType = '2' 
             AND CreateDate = MAX(t1.CorrectCreateDate) 
          ) , 
      CorrectFCVal = (SELECT MAX(rr.FCVal) 
          FROM Stc.StcDocRate AS rr 
          WHERE rr.ItemRef = t1.Id 
            AND rr.PriceType = '2' 
            AND CreateDate = MAX(t1.CorrectCreateDate) 
          ), 
      CorrectDescript = (SELECT MAX(Descript) 
           FROM Stc.StcDocRate AS rr 
           WHERE rr.ItemRef = t1.Id 
             AND rr.PriceType = '2' 
             AND CreateDate = MAX(t1.CorrectCreateDate) 
          ) , 
      AVG(t1.RealPrice)/t1.Value AS RealRate , 
      AVG(t1.RealPrice) AS RealPrice , 
      MAX(t1.RealAccDocHeaderRef) AS RealAccDocHeaderRef , 
      1 AS RealCreator , 
      1 AS RealConfirmer , 
      GETDATE() AS RealCreateDate , 
      GETDATE() AS RealConfirmDate , 
      AVG(t1.RealFCRate) AS RealFCRate , 
      AVG(t1.RealFCVal) AS RealFCVal , 
      AVG(t1.CaledPrice)/t1.Value AS CaledRate , 
      AVG(t1.CaledPrice) AS CaledPrice , 
      MAX(t1.CaledAccDocHeaderRef) AS CaledAccDocHeaderRef , 
      1 AS CaledCreator , 
      1 AS CaledConfirmer , 
      GETDATE() AS CaledCreateDate , 
      GETDATE() AS CaledConfirmDate , 
      AVG(t1.CaledFCRate) AS CaledFCRate , 
      AVG(t1.CaledFCVal) AS CaledFCVal , 
      t1.ItemNum , 
      t1.BasePartCode , 
      t1.BasePartTitle , 
      t1.DlRefHeader , 
      t1.SLRefHeader, 
      t1.ProductionValue , 
      t1.FormulaRef , 
      t1.StcDocReqRef 
    FROM (SELECT item.Id , 
         item.HeaderRef , 
         item.PartRef , 
         item.SLRef , 
         item.DL , 
         item.DL2 , 
         item.DL3 , 
         item.DL4 , 
         item.DL5 , 
         item.DL6 , 
         item.DL7 , 
         item.ItemRef , 
         item.CalItemRef , 
         item.RowNum , 
         item.UnitType , 
         UnitTypeTitle = CASE item.UnitType 
              WHEN '1' THEN N'اصلی' 
              WHEN '2' THEN N'فرعی' 
             END , 
         item.UnitRef , 
         item.Ratio , 
         item.Value , 
         item.MasterValue , 
         item.ItemDate , 
         item.Descript , 
         item.StcDocReqRef , 
         item.Year , 
         item.BranchRef , 
         item.StockRef , 
         item.OpositStockRef , 
         item.DocTypeRef , 
         item.BaseDocTypeRef , 
         item.Creator , 
         item.Confirmer , 
         item.Num , 
         item.State , 
         item.DocDate , 
         item.FCRef , 
         fc.Title AS FCTitle , 
         item.ProductionValue , 
         item.FormulaRef , 
         p.Title AS PartTitle , 
         p.Code AS PartCode , 
         sl.SLCode AS SLCode , 
         dl1.DLCode AS DL1Code , 
         dl2.DLCode AS DL2Code , 
         dl3.DLCode AS DL3Code , 
         dl4.DLCode AS DL4Code , 
         dl5.DLCode AS DL5Code , 
         dl6.DLCode AS DL6Code , 
         dl7.DLCode AS DL7Code , 
         pu.Title AS UnitTitle , 
         puslave.Title AS PartUnitTitle , 
         CorrectRate.Rate AS CorrectRate , 
         CorrectRate.Price AS CorrectPrice , 
         CorrectRate.AccDocHeaderRef AS CorrectAccDocHeaderRef , 
         CorrectRate.Creator AS CorrectCreator , 
         CorrectRate.Confirmer AS CorrectConfirmer , 
         CorrectRate.CreateDate AS CorrectCreateDate , 
         CorrectRate.ConfirmDate AS CorrectConfirmDate , 
         CorrectRate.FCRate AS CorrectFCRate , 
         CorrectRate.FCVal AS CorrectFCVal , 
         CorrectRate.Descript AS CorrectDescript , 
         realRate.Rate RealRate , 
         realRate.Price RealPrice , 
         realRate.AccDocHeaderRef AS RealAccDocHeaderRef , 
         realRate.Creator AS RealCreator , 
         realRate.Confirmer AS RealConfirmer , 
         realRate.CreateDate AS RealCreateDate , 
         realRate.ConfirmDate AS RealConfirmDate , 
         realRate.FCRate AS RealFCRate , 
         realRate.FCVal AS RealFCVal , 
         CaledRate.Rate AS CaledRate , 
         CaledRate.Price AS CaledPrice , 
         CaledRate.AccDocHeaderRef AS CaledAccDocHeaderRef , 
         CaledRate.Creator AS CaledCreator , 
         CaledRate.Confirmer AS CaledConfirmer , 
         CaledRate.CreateDate AS CaledCreateDate , 
         CaledRate.ConfirmDate AS CaledConfirmDate , 
         CaledRate.FCRate AS CaledFCRate , 
         CaledRate.FCVal AS CaledFCVal , 
         ItemNum = CASE header.BaseDocTypeRef 
            WHEN 2000 THEN refReqItem.Num 
            WHEN 2002 THEN refOrderItem.Num 
            WHEN 2003 THEN refFactItem.Num 
            WHEN 2004 THEN refRetFactItem.Num 
            WHEN 2010 THEN cmrPostItem.Num 
            WHEN 2012 THEN cmrRet.Num 
            WHEN 2016 THEN header.ProductionNum 
            ELSE refItem.Num 
            END , 
         refPart.Code AS BasePartCode , 
         refPart.Title AS BasePartTitle , 
         header.DLRef AS DlRefHeader , 
         header.SLRef AS SLRefHeader 
       FROM  Stc.StcDocItem AS item 
         INNER JOIN Stc.Part AS p ON p.Id = item.PartRef 
         LEFT OUTER JOIN Acc.SL AS sl ON sl.Id = item.SLRef 
         LEFT OUTER JOIN Acc.DL AS dl1 ON dl1.Id = item.DL 
         LEFT OUTER JOIN Acc.DL AS dl2 ON dl2.Id = item.DL2 
         LEFT OUTER JOIN Acc.DL AS dl3 ON dl3.Id = item.DL3 
         LEFT OUTER JOIN Acc.DL AS dl4 ON dl4.Id = item.DL4 
         LEFT OUTER JOIN Acc.DL AS dl5 ON dl5.Id = item.DL5 
         LEFT OUTER JOIN Acc.DL AS dl6 ON dl6.Id = item.DL6 
         LEFT OUTER JOIN Acc.DL AS dl7 ON dl7.Id = item.DL7 
         LEFT OUTER JOIN Acc.FC AS fc ON fc.Id = item.FCRef 
         LEFT OUTER JOIN Stc.PartUnit AS pu ON pu.Id = item.UnitRef 
         LEFT OUTER JOIN Stc.PartUnit AS puslave ON puslave.Id = p.UnitRef 
         LEFT OUTER JOIN Stc.StcDocRate AS realRate ON realRate.ItemRef = item.Id 
                   AND realRate.PriceType = '1' 
         LEFT OUTER JOIN Stc.StcDocRate AS CorrectRate ON CorrectRate.ItemRef = item.Id 
                   AND CorrectRate.PriceType = '2' 
         LEFT OUTER JOIN Stc.StcDocRate AS CaledRate ON CaledRate.ItemRef = item.Id 
                   AND CaledRate.PriceType = '3' 
         LEFT OUTER JOIN Stc.StcDocItem AS refItem ON refItem.Id = item.ItemRef 
         LEFT OUTER JOIN Stc.Part AS refPart ON refItem.PartRef = refPart.Id 
         LEFT OUTER JOIN Stc.StcDocReqItem AS refReqItem ON refReqItem.Id = item.ItemRef 
         LEFT OUTER JOIN Sle.SleDocOrderItem AS refOrderItem ON refOrderItem.Id = item.ItemRef 
         LEFT OUTER JOIN Sle.SleDocFactItem AS refFactItem ON refFactItem.Id = item.ItemRef 
         LEFT OUTER JOIN Sle.SleDocRetFactItem AS refRetFactItem ON refRetFactItem.Id = item.ItemRef 
         LEFT OUTER JOIN CMR.CMRIntSheetPostItem AS cmrPostItem ON cmrPostItem.Id = item.ItemRef 
         LEFT OUTER JOIN CMR.CMRIntReturnPartNonConformingItem 
         AS cmrRet ON cmrRet.Id = item.ItemRef 
         LEFT OUTER JOIN Stc.StcDocHeader AS header ON header.Id = item.HeaderRef 
      ) AS t1 

Читаемость этого запроса довольно плохая. В частности, у меня была проблема для понимания.

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

+0

Разбейте запрос на меньшие фрагменты, создав один или несколько CTE. И при этом, помимо того, что вы делаете вещи более усваиваемыми, вы даже можете получить прирост производительности. –

+0

Спасибо за вашу помощь. Можете ли вы помочь мне сделать это? –

+1

Производительность и удобочитаемость часто не совпадают. Для достижения эффективности используйте план запросов (CTRL-L), чтобы понять, где проблема с производительностью, и добавить индексы. В этом запросе, какие таблицы имеют наибольшее количество записей? Читаемость - это другое дело. Это так же понятно, как может быть. Это сложный вопрос, и все это к сожалению. –

ответ

1

1. читаемость

  • если у вас есть, чтобы получить один выход выбрать со всеми этими колонками, ваш запрос хорошо сформирован достаточно
  • , если вы можете разложить свой QRY, поэтому разбить его на более мелкий логический (или семантически связанные)
  • использовать представления для поворотного вывода - например, вместо 8x Acc.SL left join create view with pivoted data
  • использовать функции или представления, чтобы удалить регистр case или подзапросы
  • отдельного agregations и другие данные (это, кажется, в вашем QRY отсутствуют группу по заявлению)

2. производительность

  • планируйте запрос
  • переписать запрос, чтобы использовать существующие индексы или добавить отсутствующие индексы
  • принудительное соединение, если необходимо
Смежные вопросы