Sql server 如何提高SQL的可读性和性能?

Sql server 如何提高SQL的可读性和性能?,sql-server,tsql,Sql Server,Tsql,我有以下看法: 所以问题是,如何提高此查询的SQL可读性 SELECT t1.Id , t1.HeaderRef , t1.PartRef , t1.SLRef , t1.DL , t1.DL2 , t1.DL3 , t1.DL4 , t1.DL5 , t1.DL6 ,

我有以下看法: 所以问题是,如何提高此查询的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
这个查询的可读性非常差。尤其是,我很难理解


我想了解一些关于如何提高本案例的性能和可读性的反馈意见。

1。可读性

  • 如果必须对所有这些列进行一次输出选择,那么查询的格式就足够好了
  • 如果您可以分解您的qry,那么将其拆分为更小的逻辑(或语义连接)块
  • 使用视图进行数据透视输出-例如,使用数据透视创建视图,而不是8x Acc.SL left join
  • 使用函数或视图删除case语句或子查询
  • 单独的报表和其他数据(您的qry中似乎缺少分组报表)
2。性能

  • 获取查询计划
  • 重写查询以使用现有索引或添加缺少的索引
  • 如有必要,强制加入命令

通过创建一个或多个CTE,将查询拆分为更小的部分。在这样做的过程中,除了使内容更易于消化之外,您甚至可以获得性能增益。感谢您的帮助,您能帮我做到这一点吗?性能和可读性通常不会同时进行。为了提高性能,请使用查询计划(CTRL-L)了解性能问题所在,并添加索引。在此查询中,哪些表的记录最多?可读性是另一回事。它尽可能可读。这是一个复杂的查询,不幸的是,仅此而已。@TimBiegeleisen CTE很少能提高性能,如果有的话,因为它只是一个一次性视图。有用的缩进、信息丰富的别名、整洁的连接、合理的列名等等。还有一顶漂亮的帽子。我见过更糟的。我会抛弃一个几乎适用于任何语言的个人偏好:任何在下一行继续的语句都应该有悬念。例如,如果您碰巧在滚动窗口的底部看到
其中rr.ItemRef=t1.Id
,您是否会向下滚动以在下一行看到
和rr.PriceType='2'
?如果底线是,其中rr.ItemRef=t1.Id和,那么您就会知道还有更多。