2017-01-02 85 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,所以把它分解成更小的邏輯(或語義上連接)嵌段
  • 用於轉動輸出用途的觀點 - 例如不是8倍Acc.SL左連接與樞轉數據創建視圖
  • 使用功能或視圖以除去case語句或子查詢
  • 獨立agregations和其他數據(它似乎在你的QRY缺少的語句組)

2.性能

  • GET查詢計劃
  • 重寫查詢使用現有的索引或添加缺少的索引
  • 強制加入訂單,如果有必要