使用DISTINCT的SQL查询会产生巨大的性能问题

时间:2016-10-24 07:37:19

标签: sql-server-2008 query-optimization query-performance

我有一个查询来获取捐款摘要

    SELECT  CONVERT(CHAR(2), CAST(pb.PayrollDate AS DATETIME), 101)
        + '/' + CONVERT(CHAR(4), CAST(pb.PayrollDate AS DATETIME), 120) AS Closing_Month ,
        CONVERT(CHAR(6), CAST(pb.PayrollDate AS DATETIME), 112) AS Closing_Year ,
        COUNT(DISTINCT Donation.Employee)  + ( SELECT  COUNT(*)
            FROM    dbo.Donation
                    INNER JOIN PayrollBatch pbd ON Donation.PayrollBatch = pbd.ID
            WHERE   CONVERT(CHAR(6), CAST(pbd.PayrollDate AS DATETIME), 112) = CONVERT(CHAR(6), CAST(pb.PayrollDate AS DATETIME), 112)
                    AND DonationType = 5
          )AS 'Donors' ,
        COUNT (DISTINCT( CASE WHEN Donation.DonationType = 1 OR Donation.DonationType = 5  THEN CharityDetails.ID
         END ))AS 'Charities',
        ( CAST(COUNT(DISTINCT Donation.Employee) AS DECIMAL(18, 2))
          / ( SELECT    SUM(NumberOfEmployees)
              FROM      OrganisationDetail
              WHERE     ID = Donation.OrganisationDetail
                        AND IsDeleted = 0
            ) ) * 100 AS 'Participation_Rate' ,
        SUM(CASE WHEN Donation.DonationType = 1  OR Donation.DonationType = 5 THEN Donation.Amount
                 ELSE 0
            END) AS 'Employee_Donations' ,
        SUM(CASE WHEN Donation.DonationType = 2 THEN Donation.Amount
                 ELSE 0
            END) AS 'Matched_Donations' ,
        SUM(CASE WHEN Donation.DonationType = 1
                      OR Donation.DonationType = 2 OR Donation.DonationType = 5  THEN Donation.Amount
                 ELSE 0
            END) AS 'Total_Donations'
FROM    Donation
        INNER JOIN OrganisationDetail AS OrganisationDetail_1 ON Donation.OrganisationDetail = OrganisationDetail_1.ID
        INNER JOIN CharityProjectDetails ON Donation.CharityProjectDetails = CharityProjectDetails.ID
        INNER JOIN CharityDetails ON CharityProjectDetails.CharityDetails = CharityDetails.ID
        INNER JOIN PayrollBatch pb ON Donation.PayrollBatch = pb.ID
        LEFT JOIN Employee ON Donation.Employee = Employee.ID
        LEFT JOIN DonationIntent ON Donation.DonationIntent = DonationIntent.ID
        LEFT JOIN EmployeeAddress ON Employee.ID = EmployeeAddress.Employee
        LEFT JOIN dbo.PayrollBatchOther pbo ON pbo.PayrollBatch = pb.ID
GROUP BY CONVERT(CHAR(2), CAST(pb.PayrollDate AS DATETIME), 101)
        + '/' + CONVERT(CHAR(4), CAST(pb.PayrollDate AS DATETIME), 120) ,
        CONVERT(CHAR(6), CAST(pb.PayrollDate AS DATETIME), 112) ,
        Donation.OrganisationDetail
ORDER BY Closing_Year;

我需要从结果集COUNT(DISTINCT e.ID)获得唯一的捐赠者数量,但是使用不同的查询需要7到9秒才能完成执行,但如果不这样,只需1秒就可以提高性能

更新

以下是Paste The Plan

0 个答案:

没有答案