0

此查询平均需要 4 秒。它将成为存储过程中的子查询,我需要它花费一秒钟的时间。这是查询:

(select customercampaignname + ' $' + convert(varchar, cast(amount as numeric(36,2) ) ) As 'Check_Stub_Comment2' from (
    select ROW_NUMBER() OVER (ORDER BY amount desc) as rownumber, customercampaignname, amount from (
        select * from (
               select distinct d.customercampaignname
                   ,sum(d.mastercurrencyamount) As amount

                from bb02_donation d
                      JOIN bb02_donationline dl on d.donationid = dl.donationid
                      JOIN bb02_fundraiserrevenuestream frs on dl.fundraiserrevenuestreamid = frs.fundraiserrevenuestreamid and frs.fundraiserid = 1869

                where d.customercampaignname is not null 
                      and d.customercampaignname != '' 
                group by d.CustomerCampaignName
        ) as x
) as sub ) as y where rownumber = 1)
4

3 回答 3

0

我不知道这是否会运行得更快,但据我估计,这可以简化为:

Select top 1 customercampaignname + ' $' + convert(varchar(255), cast(sum(d.mastercurrencyamount) as numeric(36,2) ) ) As amount
from bb02_donation d JOIN
     bb02_donationline dl
     on d.donationid = dl.donationid JOIN
     bb02_fundraiserrevenuestream frs
     on dl.fundraiserrevenuestreamid = frs.fundraiserrevenuestreamid and frs.fundraiserid = 1869
where d.customercampaignname is not null and d.customercampaignname != '' 
group by d.CustomerCampaignName
order by sum(d.mastercurrencyamount)
于 2013-07-22T18:46:39.417 回答
0

我不知道这是否有什么不同

;WITH cte AS 
(
    select *, ROW_NUMBER() OVER (ORDER BY amount desc) as rownumber
    from (
        select distinct d.customercampaignname, sum(d.mastercurrencyamount) As amount
        from bb02_donation d
        INNER JOIN bb02_donationline dl on d.donationid = dl.donationid
        INNER JOIN bb02_fundraiserrevenuestream frs on dl.fundraiserrevenuestreamid = frs.fundraiserrevenuestreamid and frs.fundraiserid = 1869
        where d.customercampaignname is not null 
                and d.customercampaignname != '' 
        group by d.CustomerCampaignName
    ) as x
)
SELECT TOP 1 *
FROM cte 
ORDER BY RowNumber

如果表格很正常,您可能需要帮助过滤掉一些东西,例如,您可以只选择 bb02_fundraiserrevenuestream.fundraiserid = 1869,然后执行其余的查询。我不知道,这可能是一个尝试并查看执行计划的问题。

;WITH Frs AS 
( SELECT dl.fundraiserrevenuestreamid 
  FROM bb02_fundraiserrevenuestream
  WHERE fundraiserid = 1869
)
, cte AS (
    select d.customercampaignname, sum(d.mastercurrencyamount) As amount
    from Frs
    INNER JOIN bb02_donationline dl  ON dl.fundraiserrevenuestreamid = frs.fundraiserrevenuestreamid
    INNER JOIN bb02_donation d on d.donationid = dl.donationid
    where d.customercampaignname is not null 
            and d.customercampaignname != '' 
    group by d.CustomerCampaignName
)
SELECT TOP 1  customercampaignname + ' $' + convert(varchar, cast(amount as numeric(36,2) ) ) As 'Check_Stub_Comment2' 
FROM cte
ORDER BY sum(d.mastercurrencyamount)

与往常一样,INDEXES可能是这些性能问题的解决方案。

于 2013-07-22T18:58:57.987 回答
0

如果您不需要实际使用行号,那么我会选择 TOP 1 行。查询可以简化很多。我喜欢首先从表中选择最能被您的谓词过滤掉的表。希望您对 frs.fundraiserid 和参与连接的所有列都有一个良好的索引。

SELECT 
 TOP 2 customercampaignname + ' $' + CONVERT(VARCHAR(255), CAST(SUM(d.mastercurrencyamount) AS NUMERIC(36,2) ) ) AS 'Check_Stub_Comment2',
 ROW_NUMBER() OVER(ORDER BY SUM(d.mastercurrencyamount) DESC) as rownumber
FROM bb02_fundraiserrevenuestream frs
JOIN bb02_donationline dl ON
 dl.fundraiserrevenuestreamid = frs.fundraiserrevenuestreamid
JOIN bb02_donation d ON
 d.donationid = dl.donationid          
WHERE frs.fundraiserid = 1869
 AND d.customercampaignname IS NOT NULL
 AND d.customercampaignname != '' 
GROUP BY d.CustomerCampaignName
ORDER BY SUM(d.mastercurrencyamount) DESC

由于您需要能够选择第一行或第二行,因此将其包装在 CTE 或子查询中。

WITH topcampaign AS (
SELECT 
 TOP 2 customercampaignname + ' $' + CONVERT(varchar(255), CAST(SUM(d.mastercurrencyamount) AS NUMERIC(36,2) ) ) AS 'Check_Stub_Comment2',
 ROW_NUMBER() OVER(ORDER BY SUM(d.mastercurrencyamount) DESC) as rownumber
FROM bb02_fundraiserrevenuestream frs
JOIN bb02_donationline dl ON
 dl.fundraiserrevenuestreamid = frs.fundraiserrevenuestreamid
JOIN bb02_donation d ON
 d.donationid = dl.donationid          
WHERE frs.fundraiserid = 1869
 AND d.customercampaignname IS NOT NULL
 AND d.customercampaignname != '' 
GROUP BY d.CustomerCampaignName
ORDER BY SUM(d.mastercurrencyamount) DESC
)
SELECT * from topcampaign WHERE rownumber = 1

作为另一种可能的优化,我将 CONVERT 从 CTE 中取出并放入最终选择中。不确定这是否有很大帮助。

WITH topcampaign AS (
SELECT 
 TOP 2 
 customercampaignname,
 SUM(d.mastercurrencyamount) AS amount,
 ROW_NUMBER() OVER(ORDER BY SUM(d.mastercurrencyamount) DESC) as rownumber
FROM bb02_fundraiserrevenuestream frs
JOIN bb02_donationline dl ON
 dl.fundraiserrevenuestreamid = frs.fundraiserrevenuestreamid
JOIN bb02_donation d ON
 d.donationid = dl.donationid          
WHERE frs.fundraiserid = 1869
 AND d.customercampaignname IS NOT NULL
 AND d.customercampaignname != '' 
GROUP BY 
 d.CustomerCampaignName
ORDER BY 
 SUM(d.mastercurrencyamount) DESC
)
SELECT 
 rownumber,
 customercampaignname + ' $' + CONVERT(varchar(255), CAST(amount AS NUMERIC(36,2) ) ) AS 'Check_Stub_Comment2'
FROM topcampaign 
WHERE rownumber = 1
于 2013-07-22T19:42:30.487 回答