提高加入多个选择语句的性能

时间:2013-09-17 14:38:34

标签: sql join nested

这里我们在存储过程中连接多个select语句。在每个嵌套查询中,我们对年度参数和其他一些参数进行过滤。我确信有冗余会损害性能,但不确定如何改进。任何的想法?谢谢!

SELECT Months.MonthName, 
GPSDailyAccruals.MonthNumber,
GPSDailyAccruals.YearNumber,
ISNULL(GPSDailyAccruals.Amount,0) AS GPSDailyAccrualAmount,
ISNULL(GPSMonthlyAccruals.Amount,0) AS GPSMonthlyAccrualAmount,
ISNULL(GPSMonthlyAccrualsReceivable.Amount,0) AS GPSMonthlyAccrualReceivableAmount,
ISNULL(GMIDailyAccruals.Amount,0) AS GMIDailyAccrualAmount,
ISNULL(GLPayable.AMOUNT,0) AS GLPayable,
+ISNULL(Paid.AMOUNT,0) AS Paid,
ISNULL(GMIDailyAccruals.Amount,0)-ISNULL(Paid.AMOUNT,0) AS GMIvsPAID,
ISNULL(AdjustmentsLateTradeAmount.Amount,0) AS AdjustmentsLateTradeAmount,
ISNULL(GMIDailyAccruals.Amount,0) + ISNULL(AdjustmentsLateTradeAmount.Amount,0) - ISNULL(GLPayable.AMOUNT,0) AS GLOOB,
CASE WHEN ISNULL(MatchedTrades.Amount,0) <> 0 AND ISNULL(TotalTrades.Amount,0) <> 0  THEN (CONVERT(numeric,MatchedTrades.Amount) / CONVERT(numeric,TotalTrades.Amount)) * 100 ELSE 0 END AS MatchingPercentage

FROM
(
    SELECT Months.MonthNumber, 
    Months.MonthName
    FROM Months
) Months

LEFT JOIN (
SELECT MONTH(TradeDate) AS MonthNumber,
YEAR(TradeDate) AS YearNumber,
SUM(CASE WHEN RecordType = 'C' THEN Fee ELSE Fee*-1 END) AS Amount
FROM vFutureCMEGPSPay
WHERE YEAR(TradeDate) = @year
AND StatusID <> 4
AND IsCancel = 'N'
GROUP BY MONTH(TradeDate), YEAR(TradeDate)
) GPSDailyAccruals
ON Months.MonthNumber = GPSDailyAccruals.MonthNumber

LEFT JOIN (
SELECT MonthNumber,
YearNumber,
SUM(CASE WHEN RecordType = 'C' THEN Fee ELSE Fee*-1 END) AS Amount
FROM TradeCMEGPSMonthly
WHERE YearNumber = @year
AND Expired_CarryoverIndicator NOT IN ('E','C')
GROUP BY MonthNumber, YearNumber
) GPSMonthlyAccruals
ON Months.MonthNumber = GPSMonthlyAccruals.MonthNumber

LEFT JOIN (
SELECT MonthNumber,
YearNumber,
SUM(Fee) AS Amount
FROM TradeCMEGPSMonthly
WHERE YearNumber = @year
AND RecordType = 'E'
AND Expired_CarryoverIndicator NOT IN ('E','C')
GROUP BY MonthNumber, YearNumber
) GPSMonthlyAccrualsReceivable
ON Months.MonthNumber = GPSMonthlyAccrualsReceivable.MonthNumber

LEFT JOIN (
SELECT MONTH(TradeDate) AS MonthNumber,
YEAR(TradeDate) AS YearNumber,
SUM(CASE WHEN AssetClassCode = 'Z' THEN PCOMM * -1 ELSE POTHER END)*-1 AS Amount
FROM vFutureCMEGPSGMIPay
WHERE YEAR(TradeDate) = @year
AND StatusID <> 4
GROUP BY MONTH(TradeDate), YEAR(TradeDate)
) GMIDailyAccruals
ON Months.MonthNumber = GMIDailyAccruals.MonthNumber

LEFT JOIN (
SELECT 
MonthNumber,
YearNumber,
SUM(AMOUNT)*-1 AS Amount
FROM (
    SELECT DISTINCT *
    FROM GMIGeneralLedger
    WHERE YearNumber = @year
    AND GL_ACCOUNT_NBR = '4402795'
    AND ATTRIBUTE1 NOT LIKE '%GPS SETTLEMENT%'
    ) GMIGeneralLedger
GROUP BY MonthNumber, YearNumber
) GLPayable
ON Months.MonthNumber = GLPayable.MonthNumber

LEFT JOIN (
SELECT 
MonthNumber,
YearNumber,
SUM(AMOUNT) AS Amount
FROM (
    SELECT DISTINCT *
    FROM GMIGeneralLedger
    WHERE YearNumber = @year
    AND GL_ACCOUNT_NBR = '4402795'
    AND ATTRIBUTE1 LIKE '%GPS SETTLEMENT%'
    ) GMIGeneralLedger
GROUP BY MonthNumber, YearNumber
) Paid
ON Months.MonthNumber = Paid.MonthNumber    

LEFT JOIN (
SELECT AdjustmentMonth,
AdjustmentYear,
SUM(Amount)*-1 AS Amount
FROM AdjustmentFutureWFSPayable
WHERE ModuleID = 9
AND AdjustmentYear = @year
GROUP BY AdjustmentMonth, AdjustmentYear
) AdjustmentsLateTradeAmount
ON Months.MonthNumber = AdjustmentsLateTradeAmount.AdjustmentMonth

LEFT JOIN (
SELECT MONTH(TradeDate) AS MonthNumber,
YEAR(TradeDate) AS YearNumber,
COUNT(TradeStatusID) AS Amount
FROM TradeCMEGPS
INNER JOIN TradeStatus ON TradeCMEGPS.TradeID = TradeStatus.TradeID AND ModuleID = 9 AND SourceSystemID = 7
WHERE YEAR(TradeDate) = @year
AND TradeStatus.StatusID <> 4
GROUP BY MONTH(TradeDate), YEAR(TradeDate)
) TotalTrades
ON Months.MonthNumber = TotalTrades.MonthNumber

LEFT JOIN (
SELECT MONTH(TradeDate) AS MonthNumber,
YEAR(TradeDate) AS YearNumber,
COUNT(TradeStatusID) AS Amount
FROM TradeCMEGPS
INNER JOIN TradeStatus ON TradeCMEGPS.TradeID = TradeStatus.TradeID AND ModuleID = 9 AND SourceSystemID = 7
WHERE YEAR(TradeDate) = @year
AND MatchingGroupID IS NOT NULL
GROUP BY MONTH(TradeDate), YEAR(TradeDate)
) MatchedTrades
ON Months.MonthNumber = MatchedTrades.MonthNumber

1 个答案:

答案 0 :(得分:0)

这里有许多错误的东西,多个连接使用相同的基表和逻辑,只是为了得到另一个计算,在同一个连接中执行。在没有必要时,你还按年份分组。这是一个版本(某处可能有拼写错误),遵循我刚给你的建议:

SELECT  Months.MonthName, 
        GPSDailyAccruals.MonthNumber,
        @year YearNumber,
        ISNULL(GPSDailyAccruals.Amount,0) AS GPSDailyAccrualAmount,
        ISNULL(GPSMonthlyAccruals.Amount,0) AS GPSMonthlyAccrualAmount,
        ISNULL(GPSMonthlyAccruals.AmountReceivable,0) AS GPSMonthlyAccrualReceivableAmount,
        ISNULL(GMIDailyAccruals.Amount,0) AS GMIDailyAccrualAmount,
        ISNULL(GLPayable.AMOUNT*-1,0) AS GLPayable,
        ISNULL(GLPayable.AMOUNT,0) AS Paid,
        ISNULL(GMIDailyAccruals.Amount,0)-ISNULL(GLPayable.AMOUNT,0) AS GMIvsPAID,
        ISNULL(AdjustmentsLateTradeAmount.Amount,0) AS AdjustmentsLateTradeAmount,
        ISNULL(GMIDailyAccruals.Amount,0) + ISNULL(AdjustmentsLateTradeAmount.Amount,0) - ISNULL(GLPayable.AMOUNT*-1,0) AS GLOOB,
        CASE WHEN ISNULL(TotalTrades.Amount2,0) <> 0 AND ISNULL(TotalTrades.Amount1,0) <> 0  THEN (CONVERT(numeric,TotalTrades.Amount2) / CONVERT(numeric,TotalTrades.Amount1)) * 100 ELSE 0 END AS MatchingPercentage
FROM
(
    SELECT Months.MonthNumber, 
    Months.MonthName
    FROM Months
) Months
LEFT JOIN ( SELECT  MONTH(TradeDate) AS MonthNumber,
                    SUM(CASE WHEN RecordType = 'C' THEN Fee ELSE Fee*-1 END) AS Amount
            FROM vFutureCMEGPSPay
            WHERE YEAR(TradeDate) = @year
            AND StatusID <> 4
            AND IsCancel = 'N'
            GROUP BY MONTH(TradeDate)) GPSDailyAccruals
    ON Months.MonthNumber = GPSDailyAccruals.MonthNumber
LEFT JOIN ( SELECT  MonthNumber,
                    SUM(CASE WHEN RecordType = 'C' THEN Fee ELSE Fee*-1 END) AS Amount,
                    SUM(CASE WHEN RecordType = 'E' THEN Fee END) AmountReceivable
            FROM TradeCMEGPSMonthly
            WHERE YearNumber = @year
            AND Expired_CarryoverIndicator NOT IN ('E','C')
            GROUP BY MonthNumber) GPSMonthlyAccruals
    ON Months.MonthNumber = GPSMonthlyAccruals.MonthNumber
LEFT JOIN ( SELECT  MONTH(TradeDate) AS MonthNumber,
                    SUM(CASE WHEN AssetClassCode = 'Z' THEN PCOMM * -1 ELSE POTHER END)*-1 AS Amount
            FROM vFutureCMEGPSGMIPay
            WHERE YEAR(TradeDate) = @year
            AND StatusID <> 4
            GROUP BY MONTH(TradeDate)) GMIDailyAccruals
    ON Months.MonthNumber = GMIDailyAccruals.MonthNumber
LEFT JOIN ( SELECT  MonthNumber,
                    SUM(AMOUNT) AS Amount
            FROM (  SELECT DISTINCT *
                    FROM GMIGeneralLedger
                    WHERE YearNumber = @year
                    AND GL_ACCOUNT_NBR = '4402795'
                    AND ATTRIBUTE1 NOT LIKE '%GPS SETTLEMENT%'
                  ) GMIGeneralLedger
            GROUP BY MonthNumber) GLPayable
    ON Months.MonthNumber = GLPayable.MonthNumber   
LEFT JOIN ( SELECT  AdjustmentMonth,
                    SUM(Amount)*-1 AS Amount
            FROM AdjustmentFutureWFSPayable
            WHERE ModuleID = 9
            AND AdjustmentYear = @year
            GROUP BY AdjustmentMonth) AdjustmentsLateTradeAmount
    ON Months.MonthNumber = AdjustmentsLateTradeAmount.AdjustmentMonth
LEFT JOIN ( SELECT  MONTH(TradeDate) AS MonthNumber,
                    COUNT(CASE WHEN TradeStatus.StatusID <> 4 THEN TradeStatusID END) AS Amount1,
                    COUNT(CASE WHEN MatchingGroupID IS NOT NULL THEN TradeStatusID END) AS Amount2
            FROM TradeCMEGPS
            INNER JOIN TradeStatus 
                ON TradeCMEGPS.TradeID = TradeStatus.TradeID 
                AND ModuleID = 9 AND SourceSystemID = 7
            WHERE YEAR(TradeDate) = @year
            GROUP BY MONTH(TradeDate)) TotalTrades
    ON Months.MonthNumber = TotalTrades.MonthNumber