【问题标题】:Query optimization?查询优化?
【发布时间】:2013-12-17 08:01:34
【问题描述】:

大家好,我有单独的 12 个查询和一些 c# 代码来获取页面上的数据格式,但现在我们将这些页面转换为 SSRS 报告。我已经构建了存储过程,它结合了 12 个查询和一些新的附加查询,以按照我们在 ssrs 报告上的需要格式化数据。现在新存储过程比旧页面花费更多时间,这是我的查询,可以对以下存储过程进行任何优化,任何帮助都会很棒。

CREATE PROCEDURE [dbo].[GetHistoryByYear_Get] 
-- Add the parameters for the stored procedure here    
@Year AS VARCHAR(4),
@PreYear AS VARCHAR(4)
AS
BEGIN
SET NOCOUNT ON;  
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

SELECT *  
INTO #tempCustVol
FROM 
    ( 
SELECT *  FROM 
    (   
        SELECT * FROM (
        SELECT @Year AS 'Year',Company, Customer,SUM(Jan) AS Jan, SUM(Feb) AS Feb, SUM(Mar) As Mar, SUM(Apr) AS Apr, SUM(May) AS May, SUM(Jun) AS Jun, SUM(Jul) AS Jul, SUM(Aug) AS Aug, SUM(Sep) AS Sep, SUM(Oct) AS Oct, SUM(Nov) AS Nov, SUM(Dec) AS Dec    
        ,(SUM(Jan) + SUM(Feb) + SUM(Mar) + SUM(Apr) + SUM(May) + SUM(Jun) + SUM(Jul) + SUM(Aug) + SUM(Sep) + SUM(Oct) + SUM(Nov) + SUM(Dec) ) AS YearlyTotal    
        FROM(    
            SELECT Company, Customer, DateRcvd, SUM(Records) AS Jan, 0 AS Feb, 0 As Mar, 0 As Apr, 0 As May, 0 As Jun, 0 As Jul, 0 As Aug, 0 As Sep, 0 As Oct, 0 As Nov, 0 As Dec    
            FROM(    
                select * from vwjmrep where datercvd >=@Year + '0101' and datercvd <= @Year + '1231' AND SUBSTRING(DateRcvd,5,2) = '01' AND Company IS NOT NULL    
                )  AS T    
            GROUP BY Company, Customer, DateRcvd    
            UNION    
            SELECT Company, Customer, DateRcvd, 0 AS Jan, SUM(RECORDS) AS Feb, 0 As Mar, 0 As Apr, 0 As May, 0 As Jun, 0 As Jul, 0 As Aug, 0 As Sep, 0 As Oct, 0 As Nov, 0 As Dec    
            FROM(    
                select * from vwjmrep where datercvd >=@Year + '0101' and datercvd <= @Year + '1231' AND SUBSTRING(DateRcvd,5,2) = '02' AND Company IS NOT NULL    
                )  AS T    
            GROUP BY Company, Customer, DateRcvd    
            UNION    
            SELECT Company, Customer, DateRcvd, 0 AS Jan, 0 AS Feb, SUM(RECORDS) As Mar, 0 As Apr, 0 As May, 0 As Jun, 0 As Jul, 0 As Aug, 0 As Sep, 0 As Oct, 0 As Nov, 0 As Dec    
            FROM(    
                select * from vwjmrep where datercvd >=@Year + '0101' and datercvd <= @Year + '1231' AND SUBSTRING(DateRcvd,5,2) = '03' AND Company IS NOT NULL    
                )  AS T    
            GROUP BY Company, Customer, DateRcvd    
            UNION    
            SELECT Company, Customer, DateRcvd, 0 AS Jan, 0 AS Feb, 0 As Mar, SUM(RECORDS) As Apr, 0 As May, 0 As Jun, 0 As Jul, 0 As Aug, 0 As Sep, 0 As Oct, 0 As Nov, 0 As Dec    
            FROM(    
                select * from vwjmrep where datercvd >=@Year + '0101' and datercvd <= @Year + '1231' AND SUBSTRING(DateRcvd,5,2) = '04' AND Company IS NOT NULL    
                )  AS T    
            GROUP BY Company, Customer, DateRcvd    
            UNION    
            SELECT Company, Customer, DateRcvd, 0 AS Jan, 0 AS Feb, 0 As Mar, 0 As Apr, SUM(RECORDS) As May, 0 As Jun, 0 As Jul, 0 As Aug, 0 As Sep, 0 As Oct, 0 As Nov, 0 As Dec    
            FROM(    
                select * from vwjmrep where datercvd >=@Year + '0101' and datercvd <= @Year + '1231' AND SUBSTRING(DateRcvd,5,2) = '05' AND Company IS NOT NULL    
                )  AS T    
            GROUP BY Company, Customer, DateRcvd    
            UNION    
            SELECT Company, Customer, DateRcvd, 0 AS Jan, 0 AS Feb, 0 As Mar, 0 As Apr, 0 As May, SUM(RECORDS) As Jun, 0 As Jul, 0 As Aug, 0 As Sep, 0 As Oct, 0 As Nov, 0 As Dec    
            FROM(    
                select * from vwjmrep where datercvd >=@Year + '0101' and datercvd <= @Year + '1231' AND SUBSTRING(DateRcvd,5,2) = '06' AND Company IS NOT NULL    
                )  AS T    
            GROUP BY Company, Customer, DateRcvd    
            UNION    
            SELECT Company, Customer, DateRcvd, 0 AS Jan, 0 AS Feb, 0 As Mar, 0 As Apr, 0 As May, 0 As Jun, SUM(RECORDS) As Jul, 0 As Aug, 0 As Sep, 0 As Oct, 0 As Nov, 0 As Dec    
            FROM(    
                select * from vwjmrep where datercvd >=@Year + '0101' and datercvd <= @Year + '1231' AND SUBSTRING(DateRcvd,5,2) = '07' AND Company IS NOT NULL    
                )  AS T    
            GROUP BY Company, Customer, DateRcvd    
            UNION    
            SELECT Company, Customer, DateRcvd, 0 AS Jan, 0 AS Feb, 0 As Mar, 0 As Apr, 0 As May, 0 As Jun, 0 As Jul, SUM(RECORDS) As Aug, 0 As Sep, 0 As Oct, 0 As Nov, 0 As Dec    
            FROM(    
                select * from vwjmrep where datercvd >=@Year + '0101' and datercvd <= @Year + '1231' AND SUBSTRING(DateRcvd,5,2) = '08' AND Company IS NOT NULL    
                )  AS T    
            GROUP BY Company, Customer, DateRcvd    
            UNION    
            SELECT Company, Customer, DateRcvd, 0 AS Jan, 0 AS Feb, 0 As Mar, 0 As Apr, 0 As May, 0 As Jun, 0 As Jul, 0 As Aug, SUM(RECORDS) As Sep, 0 As Oct, 0 As Nov, 0 As Dec    
            FROM(    
                select * from vwjmrep where datercvd >=@Year + '0101' and datercvd <= @Year + '1231' AND SUBSTRING(DateRcvd,5,2) = '09' AND Company IS NOT NULL    
                )  AS T    
            GROUP BY Company, Customer, DateRcvd    
            UNION    
            SELECT Company, Customer, DateRcvd, 0 AS Jan, 0 AS Feb, 0 As Mar, 0 As Apr, 0 As May, 0 As Jun, 0 As Jul, 0 As Aug, 0 As Sep, SUM(RECORDS) As Oct, 0 As Nov, 0 As Dec    
            FROM(    
                select * from vwjmrep where datercvd >=@Year + '0101' and datercvd <= @Year + '1231' AND SUBSTRING(DateRcvd,5,2) = '10' AND Company IS NOT NULL    
                )  AS T    
            GROUP BY Company, Customer, DateRcvd    
            UNION    
            SELECT Company, Customer, DateRcvd, 0 AS Jan, 0 AS Feb, 0 As Mar, 0 As Apr, 0 As May, 0 As Jun, 0 As Jul, 0 As Aug, 0 As Sep, 0 As Oct, SUM(RECORDS) As Nov, 0 As Dec    
            FROM(    
                select * from vwjmrep where datercvd >=@Year + '0101' and datercvd <= @Year + '1231' AND SUBSTRING(DateRcvd,5,2) = '11' AND Company IS NOT NULL    
                )  AS T    
            GROUP BY Company, Customer, DateRcvd    
            UNION    
            SELECT Company, Customer, DateRcvd, 0 AS Jan, 0 AS Feb, 0 As Mar, 0 As Apr, 0 As May, 0 As Jun, 0 As Jul, 0 As Aug, 0 As Sep, 0 As Oct, 0 As Nov, SUM(RECORDS) As Dec    
            FROM(    
                select * from vwjmrep where datercvd >=@Year + '0101' and datercvd <= @Year + '1231' AND SUBSTRING(DateRcvd,5,2) = '12' AND Company IS NOT NULL    
                )  AS T    
            GROUP BY Company, Customer, DateRcvd    
            ) F    
        GROUP BY Company, Customer
        ) AS ALLDATA

        UNION 

        SELECT * FROM (
        SELECT @PreYear AS 'Year',Company, Customer,SUM(Jan) AS Jan, SUM(Feb) AS Feb, SUM(Mar) As Mar, SUM(Apr) AS Apr, SUM(May) AS May, SUM(Jun) AS Jun, SUM(Jul) AS Jul, SUM(Aug) AS Aug, SUM(Sep) AS Sep, SUM(Oct) AS Oct, SUM(Nov) AS Nov, SUM(Dec) AS Dec    
        ,(SUM(Jan) + SUM(Feb) + SUM(Mar) + SUM(Apr) + SUM(May) + SUM(Jun) + SUM(Jul) + SUM(Aug) + SUM(Sep) + SUM(Oct) + SUM(Nov) + SUM(Dec) ) AS YearlyTotal    
        FROM(    
            SELECT Company, Customer, DateRcvd, SUM(Records) AS Jan, 0 AS Feb, 0 As Mar, 0 As Apr, 0 As May, 0 As Jun, 0 As Jul, 0 As Aug, 0 As Sep, 0 As Oct, 0 As Nov, 0 As Dec    
            FROM(    
                select * from vwjmrep where datercvd >=@PreYear + '0101' and datercvd <= @PreYear + '1231' AND SUBSTRING(DateRcvd,5,2) = '01' AND Company IS NOT NULL    
                )  AS T    
            GROUP BY Company, Customer, DateRcvd    
            UNION    
            SELECT Company, Customer, DateRcvd, 0 AS Jan, SUM(RECORDS) AS Feb, 0 As Mar, 0 As Apr, 0 As May, 0 As Jun, 0 As Jul, 0 As Aug, 0 As Sep, 0 As Oct, 0 As Nov, 0 As Dec    
            FROM(    
                select * from vwjmrep where datercvd >=@PreYear + '0101' and datercvd <= @PreYear + '1231' AND SUBSTRING(DateRcvd,5,2) = '02' AND Company IS NOT NULL    
                )  AS T    
            GROUP BY Company, Customer, DateRcvd    
            UNION    
            SELECT Company, Customer, DateRcvd, 0 AS Jan, 0 AS Feb, SUM(RECORDS) As Mar, 0 As Apr, 0 As May, 0 As Jun, 0 As Jul, 0 As Aug, 0 As Sep, 0 As Oct, 0 As Nov, 0 As Dec    
            FROM(    
                select * from vwjmrep where datercvd >=@PreYear + '0101' and datercvd <= @PreYear + '1231' AND SUBSTRING(DateRcvd,5,2) = '03' AND Company IS NOT NULL    
                )  AS T    
            GROUP BY Company, Customer, DateRcvd    
            UNION    
            SELECT Company, Customer, DateRcvd, 0 AS Jan, 0 AS Feb, 0 As Mar, SUM(RECORDS) As Apr, 0 As May, 0 As Jun, 0 As Jul, 0 As Aug, 0 As Sep, 0 As Oct, 0 As Nov, 0 As Dec    
            FROM(    
                select * from vwjmrep where datercvd >=@PreYear + '0101' and datercvd <= @PreYear + '1231' AND SUBSTRING(DateRcvd,5,2) = '04' AND Company IS NOT NULL    
                )  AS T    
            GROUP BY Company, Customer, DateRcvd    
            UNION    
            SELECT Company, Customer, DateRcvd, 0 AS Jan, 0 AS Feb, 0 As Mar, 0 As Apr, SUM(RECORDS) As May, 0 As Jun, 0 As Jul, 0 As Aug, 0 As Sep, 0 As Oct, 0 As Nov, 0 As Dec    
            FROM(    
                select * from vwjmrep where datercvd >=@PreYear + '0101' and datercvd <= @PreYear + '1231' AND SUBSTRING(DateRcvd,5,2) = '05' AND Company IS NOT NULL    
                )  AS T    
            GROUP BY Company, Customer, DateRcvd    
            UNION    
            SELECT Company, Customer, DateRcvd, 0 AS Jan, 0 AS Feb, 0 As Mar, 0 As Apr, 0 As May, SUM(RECORDS) As Jun, 0 As Jul, 0 As Aug, 0 As Sep, 0 As Oct, 0 As Nov, 0 As Dec    
            FROM(    
                select * from vwjmrep where datercvd >=@PreYear + '0101' and datercvd <= @PreYear + '1231' AND SUBSTRING(DateRcvd,5,2) = '06' AND Company IS NOT NULL    
                )  AS T    
            GROUP BY Company, Customer, DateRcvd    
            UNION    
            SELECT Company, Customer, DateRcvd, 0 AS Jan, 0 AS Feb, 0 As Mar, 0 As Apr, 0 As May, 0 As Jun, SUM(RECORDS) As Jul, 0 As Aug, 0 As Sep, 0 As Oct, 0 As Nov, 0 As Dec    
            FROM(    
                select * from vwjmrep where datercvd >=@PreYear + '0101' and datercvd <= @PreYear + '1231' AND SUBSTRING(DateRcvd,5,2) = '07' AND Company IS NOT NULL    
                )  AS T    
            GROUP BY Company, Customer, DateRcvd    
            UNION    
            SELECT Company, Customer, DateRcvd, 0 AS Jan, 0 AS Feb, 0 As Mar, 0 As Apr, 0 As May, 0 As Jun, 0 As Jul, SUM(RECORDS) As Aug, 0 As Sep, 0 As Oct, 0 As Nov, 0 As Dec    
            FROM(    
                select * from vwjmrep where datercvd >=@PreYear + '0101' and datercvd <= @PreYear + '1231' AND SUBSTRING(DateRcvd,5,2) = '08' AND Company IS NOT NULL    
                )  AS T    
            GROUP BY Company, Customer, DateRcvd    
            UNION    
            SELECT Company, Customer, DateRcvd, 0 AS Jan, 0 AS Feb, 0 As Mar, 0 As Apr, 0 As May, 0 As Jun, 0 As Jul, 0 As Aug, SUM(RECORDS) As Sep, 0 As Oct, 0 As Nov, 0 As Dec    
            FROM(    
                select * from vwjmrep where datercvd >=@PreYear + '0101' and datercvd <= @PreYear + '1231' AND SUBSTRING(DateRcvd,5,2) = '09' AND Company IS NOT NULL    
                )  AS T    
            GROUP BY Company, Customer, DateRcvd    
            UNION    
            SELECT Company, Customer, DateRcvd, 0 AS Jan, 0 AS Feb, 0 As Mar, 0 As Apr, 0 As May, 0 As Jun, 0 As Jul, 0 As Aug, 0 As Sep, SUM(RECORDS) As Oct, 0 As Nov, 0 As Dec    
            FROM(    
                select * from vwjmrep where datercvd >=@PreYear + '0101' and datercvd <= @PreYear + '1231' AND SUBSTRING(DateRcvd,5,2) = '10' AND Company IS NOT NULL    
                )  AS T    
            GROUP BY Company, Customer, DateRcvd    
            UNION    
            SELECT Company, Customer, DateRcvd, 0 AS Jan, 0 AS Feb, 0 As Mar, 0 As Apr, 0 As May, 0 As Jun, 0 As Jul, 0 As Aug, 0 As Sep, 0 As Oct, SUM(RECORDS) As Nov, 0 As Dec    
            FROM(    
                select * from vwjmrep where datercvd >=@PreYear + '0101' and datercvd <= @PreYear + '1231' AND SUBSTRING(DateRcvd,5,2) = '11' AND Company IS NOT NULL    
                )  AS T    
            GROUP BY Company, Customer, DateRcvd    
            UNION    
            SELECT Company, Customer, DateRcvd, 0 AS Jan, 0 AS Feb, 0 As Mar, 0 As Apr, 0 As May, 0 As Jun, 0 As Jul, 0 As Aug, 0 As Sep, 0 As Oct, 0 As Nov, SUM(RECORDS) As Dec    
            FROM(    
                select * from vwjmrep where datercvd >=@PreYear + '0101' and datercvd <= @PreYear + '1231' AND SUBSTRING(DateRcvd,5,2) = '12' AND Company IS NOT NULL    
                )  AS T    
            GROUP BY Company, Customer, DateRcvd    
            ) F    
        GROUP BY Company, Customer
        ) AS ALLDATA
    ) AS TEMPDATA
    ) AS data

SELECT * FROM (SELECT * FROM #tempCustVol
UNION
SELECT 
    @PreYear AS [Year],null,null,COALESCE(SUM(Jan),0),COALESCE(SUM(Feb),0),COALESCE(SUM(Mar),0),COALESCE(SUM(Apr),0),
    COALESCE(SUM(May),0),COALESCE(SUM(Jun),0),COALESCE(SUM(Jul),0),COALESCE(SUM(Aug),0),COALESCE(SUM(Sep),0),COALESCE(SUM(Oct),0),
    COALESCE(SUM(Nov),0),COALESCE(SUM(Dec),0),COALESCE((SUM(Jan) + SUM(Feb) + SUM(Mar) + SUM(Apr) + SUM(May) + SUM(Jun) + SUM(Jul) + SUM(Aug) + SUM(Sep) + SUM(Oct) + SUM(Nov) + SUM(Dec) ),0) AS YearlyTotal
FROM #tempCustVol
WHERE [Year] = @PreYear
)AS DA
ORDER BY 
    CASE WHEN Company is null THEN 1 ELSE 0 END,
    Company,[Year]

DROP TABLE #tempCustVol
END

任何帮助都会很棒,我已经为表格编制了索引,并且表格中有大量数据,大约需要 10 到 12 分钟才能执行,有什么办法可以最小化它。它是 SQL SERVER 2008 数据库

更新


这是我更新的存储过程

BEGIN
DECLARE @Year AS VARCHAR(4),
@PreYear AS VARCHAR(4)
SET  @Year='2013'
SET @PreYear='2012'
SET NOCOUNT ON;  
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

SELECT *  
INTO #tempCustVol
FROM 
    ( 
SELECT *  FROM 
    (   
        SELECT * FROM (
            SELECT @Year AS 'Year',Company, Customer,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '01' THEN Records ELSE 0 END) AS Jan,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '02' THEN Records ELSE 0 END) AS Feb,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '03' THEN Records ELSE 0 END) AS Mar,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '04' THEN Records ELSE 0 END) AS Apr,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '05' THEN Records ELSE 0 END) AS May,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '06' THEN Records ELSE 0 END) AS Jun,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '07' THEN Records ELSE 0 END) AS Jul,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '08' THEN Records ELSE 0 END) AS Aug,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '09' THEN Records ELSE 0 END) AS Sep,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '10' THEN Records ELSE 0 END) AS Oct,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '11' THEN Records ELSE 0 END) AS Nov,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '12' THEN Records ELSE 0 END) AS Dec,
            SUM(Records) AS YearlyTotal    
        FROM  vwjmrep
        WHERE datercvd >=@Year + '0101' and datercvd <= @Year + '1231'  AND Company IS NOT NULL 
        GROUP BY Company, Customer
        ) AS ALLDATA
        UNION ALL
        SELECT * FROM (
        SELECT @PreYear AS 'Year',Company, Customer,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '01' THEN Records ELSE 0 END) AS Jan,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '02' THEN Records ELSE 0 END) AS Feb,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '03' THEN Records ELSE 0 END) AS Mar,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '04' THEN Records ELSE 0 END) AS Apr,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '05' THEN Records ELSE 0 END) AS May,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '06' THEN Records ELSE 0 END) AS Jun,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '07' THEN Records ELSE 0 END) AS Jul,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '08' THEN Records ELSE 0 END) AS Aug,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '09' THEN Records ELSE 0 END) AS Sep,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '10' THEN Records ELSE 0 END) AS Oct,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '11' THEN Records ELSE 0 END) AS Nov,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '12' THEN Records ELSE 0 END) AS Dec,
            SUM(Records) AS YearlyTotal    
        FROM  vwjmrep
        WHERE datercvd >=@PreYear + '0101' and datercvd <= @PreYear + '1231'  AND Company IS NOT NULL 
        GROUP BY Company, Customer
        ) AS ALLDATA
    ) AS TEMPDATA
    ) AS data

SELECT * FROM (SELECT * FROM #tempCustVol
UNION ALL
SELECT 
    @PreYear AS [Year],null,null,COALESCE(SUM(Jan),0),COALESCE(SUM(Feb),0),COALESCE(SUM(Mar),0),COALESCE(SUM(Apr),0),
    COALESCE(SUM(May),0),COALESCE(SUM(Jun),0),COALESCE(SUM(Jul),0),COALESCE(SUM(Aug),0),COALESCE(SUM(Sep),0),COALESCE(SUM(Oct),0),
    COALESCE(SUM(Nov),0),COALESCE(SUM(Dec),0),COALESCE((SUM(Jan) + SUM(Feb) + SUM(Mar) + SUM(Apr) + SUM(May) + SUM(Jun) + SUM(Jul) + SUM(Aug) + SUM(Sep) + SUM(Oct) + SUM(Nov) + SUM(Dec) ),0) AS YearlyTotal
FROM #tempCustVol
WHERE [Year] = @PreYear
)AS DA
ORDER BY 
    CASE WHEN Company is null THEN 1 ELSE 0 END,
    Company,[Year]

DROP TABLE #tempCustVol
END

这仍然需要时间,但是否可以进行更多优化,谢谢

【问题讨论】:

  • 您是否尝试过 SSMS 中的查询优化器/SQL 索引调优选项?这通常是一个不错的起点。
  • 我不喜欢这种结构,但是第一个帮助。将 UNION 更改为 UNION ALL(您的集合不同),您没有重复。
  • @JohnFx Thaks 我试过了。
  • @MitchWheat 呀!我知道!
  • @JoeTaras 是的,这将时间缩短了几秒,感谢您的帮助,但是我可以遵循任何其他结构来尽快获得结果

标签: sql sql-server stored-procedures query-optimization query-performance


【解决方案1】:

我想,你可以试试替换这个

SELECT * FROM (
    SELECT @Year AS 'Year',Company, Customer,SUM(Jan) AS Jan, SUM(Feb) AS Feb, SUM(Mar) As Mar, SUM(Apr) AS Apr, SUM(May) AS May, SUM(Jun) AS Jun, SUM(Jul) AS Jul, SUM(Aug) AS Aug, SUM(Sep) AS Sep, SUM(Oct) AS Oct, SUM(Nov) AS Nov, SUM(Dec) AS Dec    
    ,(SUM(Jan) + SUM(Feb) + SUM(Mar) + SUM(Apr) + SUM(May) + SUM(Jun) + SUM(Jul) + SUM(Aug) + SUM(Sep) + SUM(Oct) + SUM(Nov) + SUM(Dec) ) AS YearlyTotal    
    FROM(    
        SELECT Company, Customer, DateRcvd, SUM(Records) AS Jan, 0 AS Feb, 0 As Mar, 0 As Apr, 0 As May, 0 As Jun, 0 As Jul, 0 As Aug, 0 As Sep, 0 As Oct, 0 As Nov, 0 As Dec    
        FROM(    
            select * from vwjmrep where datercvd >=@Year + '0101' and datercvd <= @Year + '1231' AND SUBSTRING(DateRcvd,5,2) = '01' AND Company IS NOT NULL    
            )  AS T    
        GROUP BY Company, Customer, DateRcvd    
        UNION    
        SELECT Company, Customer, DateRcvd, 0 AS Jan, SUM(RECORDS) AS Feb, 0 As Mar, 0 As Apr, 0 As May, 0 As Jun, 0 As Jul, 0 As Aug, 0 As Sep, 0 As Oct, 0 As Nov, 0 As Dec    
        FROM(    
            select * from vwjmrep where datercvd >=@Year + '0101' and datercvd <= @Year + '1231' AND SUBSTRING(DateRcvd,5,2) = '02' AND Company IS NOT NULL    
            )  AS T    
        GROUP BY Company, Customer, DateRcvd   

GROUP BY Company, Customer

有了这个

 SELECT @Year AS 'Year',Company, Customer,
    SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '01' THEN Records ELSE 0 END) AS Jan,
    SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '02' THEN Records ELSE 0 END) AS Feb,
    ...,
    SUM(Records) AS YearlyTotal    
    FROM  vwjmrep
WHERE datercvd >=@Year + '0101' and datercvd <= @Year + '1231'  AND Company IS NOT NULL 
GROUP BY Company, Customer

至少,表扫描会更少。

【讨论】:

  • 感谢伙伴,它帮了很多忙,几乎将执行时间缩短到几秒钟,再次感谢
  • 鉴于这是 SQL Server,您真的不想对 date/time/timestamps 使用包容性上限。此外,您可以计算年度总计和每月总计,您不需要单独包装。
  • @Clockwork-Muse 嗨。我没明白你评论的意义何在。答案与给定查询的优化有关,它实际上必须将表扫描次数减少 12。我不知道为什么作者将这个条件用于日期,因为我不知道 datercvd 的数据类型是什么。我只是为此复制粘贴了作者的代码。
  • 呃,对“总和”部分感到抱歉(评论从下面复制)。至于处理日期 - 虽然我确实怀疑 datercvd 是字符,但最好将其处理为有可能成为实际的日期/时间戳类型(鉴于边界表格采用安全可翻译的格式)。这样,可以安全地更改列的类型,而不会影响查询;但是,对于当前版本,更改列的类型也需要更改查询(因为上限不会选择给定日期的 all)。
  • @Curiosity 我认为,在 vwjmrep (datercvd) 上添加索引可以提高性能。
【解决方案2】:

看看这个

CREATE PROCEDURE [dbo].[GetHistoryByYear_Get] 
-- Add the parameters for the stored procedure here    
@Year AS VARCHAR(4),
@PreYear AS VARCHAR(4)
AS
BEGIN
SET NOCOUNT ON;  
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

SELECT *  
INTO #tempCustVol
FROM 
( 
SELECT *
        , Jan + Feb + Mar + Apr + May + Jun + Jul + Aug + Sep + Oct + Nov + [Dec] AS YearlyTotal 
FROM (
SELECT @Year AS 'Year', Company, Customer,
    SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '01' THEN Records ELSE 0)) Jan,
    SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '02' THEN Records ELSE 0)) Feb,
    SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '03' THEN Records ELSE 0)) Mar,
    SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '04' THEN Records ELSE 0)) Apr,
    SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '05' THEN Records ELSE 0)) May,
    SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '06' THEN Records ELSE 0)) Jun,
    SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '07' THEN Records ELSE 0)) Jul,
    SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '08' THEN Records ELSE 0)) Aug,
    SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '09' THEN Records ELSE 0)) Sep,
    SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '10' THEN Records ELSE 0)) Oct,
    SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '11' THEN Records ELSE 0)) Nov,
    SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '12' THEN Records ELSE 0)) [Dec]
FROM vwjmrep
WHERE   Company IS NOT NULL
        AND (datercvd >=@Year + '0101' AND datercvd <= @Year + '1231')
GROUP BY Company, Customer
UNION ALL
SELECT @PreYear AS 'Year', Company, Customer,
    SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '01' THEN Records ELSE 0)) Jan,
    SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '02' THEN Records ELSE 0)) Feb,
    SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '03' THEN Records ELSE 0)) Mar,
    SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '04' THEN Records ELSE 0)) Apr,
    SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '05' THEN Records ELSE 0)) May,
    SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '06' THEN Records ELSE 0)) Jun,
    SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '07' THEN Records ELSE 0)) Jul,
    SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '08' THEN Records ELSE 0)) Aug,
    SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '09' THEN Records ELSE 0)) Sep,
    SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '10' THEN Records ELSE 0)) Oct,
    SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '11' THEN Records ELSE 0)) Nov,
    SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '12' THEN Records ELSE 0)) [Dec]
FROM vwjmrep
WHERE   Company IS NOT NULL
        AND (datercvd >=@PreYear + '0101' AND datercvd <= @PreYear + '1231')
GROUP BY Company, Customer
) x
) ALLDATA
...Rest of the code here

【讨论】:

  • 鉴于这是 SQL Server,您真的不想对 date/time/timestamps 使用包容性上限。此外,您可以计算年度总计和每月总计,您不需要单独包装。
【解决方案3】:

关于我的最后一条评论:- 我仍然坚持。在 sql 中做一些事情,在 C# 中做一些事情,特别是当查询如此繁重时。你的查询也没有分页。所以如果超过 100 个,优化查询无济于事rows.Also 你也可以使用索引。 好的,看看这个,如果它没有运行,那么告诉

;With CTE as
(SELECT @Year AS 'Year',Company, Customer,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '01' THEN Records ELSE 0 END) AS Jan,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '02' THEN Records ELSE 0 END) AS Feb,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '03' THEN Records ELSE 0 END) AS Mar,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '04' THEN Records ELSE 0 END) AS Apr,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '05' THEN Records ELSE 0 END) AS May,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '06' THEN Records ELSE 0 END) AS Jun,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '07' THEN Records ELSE 0 END) AS Jul,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '08' THEN Records ELSE 0 END) AS Aug,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '09' THEN Records ELSE 0 END) AS Sep,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '10' THEN Records ELSE 0 END) AS Oct,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '11' THEN Records ELSE 0 END) AS Nov,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '12' THEN Records ELSE 0 END) AS Dec,
            SUM(Records) AS YearlyTotal    
        FROM  vwjmrep
        WHERE datercvd >=@Year + '0101' and datercvd <= @Year + '1231'  AND Company IS NOT NULL 
        GROUP BY Company, Customer
Union All

SELECT @PreYear AS 'Year',Company, Customer,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '01' THEN Records ELSE 0 END) AS Jan,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '02' THEN Records ELSE 0 END) AS Feb,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '03' THEN Records ELSE 0 END) AS Mar,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '04' THEN Records ELSE 0 END) AS Apr,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '05' THEN Records ELSE 0 END) AS May,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '06' THEN Records ELSE 0 END) AS Jun,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '07' THEN Records ELSE 0 END) AS Jul,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '08' THEN Records ELSE 0 END) AS Aug,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '09' THEN Records ELSE 0 END) AS Sep,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '10' THEN Records ELSE 0 END) AS Oct,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '11' THEN Records ELSE 0 END) AS Nov,
            SUM(CASE WHEN SUBSTRING(DateRcvd,5,2) = '12' THEN Records ELSE 0 END) AS Dec,
            SUM(Records) AS YearlyTotal    
        FROM  vwjmrep
        WHERE datercvd >=@PreYear + '0101' and datercvd <= @PreYear + '1231'  AND Company IS NOT NULL 
        GROUP BY Company, Customer
)
,CTE1 as
(Select * from cte
union all
SELECT 
    @PreYear AS [Year],null,null,COALESCE(SUM(Jan),0),COALESCE(SUM(Feb),0),COALESCE(SUM(Mar),0),COALESCE(SUM(Apr),0),
    COALESCE(SUM(May),0),COALESCE(SUM(Jun),0),COALESCE(SUM(Jul),0),COALESCE(SUM(Aug),0),COALESCE(SUM(Sep),0),COALESCE(SUM(Oct),0),
    COALESCE(SUM(Nov),0),COALESCE(SUM(Dec),0),COALESCE((SUM(Jan) + SUM(Feb) + SUM(Mar) + SUM(Apr) + SUM(May) + SUM(Jun) + SUM(Jul) + SUM(Aug) + SUM(Sep) + SUM(Oct) + SUM(Nov) + SUM(Dec) ),0) AS YearlyTotal
FROM cte
WHERE [Year] = @PreYear
)
select * from cte1
ORDER BY 
    CASE WHEN Company is null THEN 1 ELSE 0 END,
    Company,[Year]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-25
    • 2012-06-15
    • 2011-01-19
    相关资源
    最近更新 更多