如何优化此查询(东西部分)

时间:2014-01-28 17:34:50

标签: sql sql-server sql-server-2008

如何优化以下查询:

SELECT 

MONTH('1' + LEFT(Datename(month,visitDate),3) +'00') AS MONTH_NUMBER ,

VisitMonth = LEFT(Datename(month,visitDate),3)

,TotalVisits = Count(v.VisitID)

,TotalVisits_with_StandardReport = Count(CASE WHEN v.ReportStandard NOT IN (0,9) THEN   v.ReportStandard END)

,TotalVisits_with_FeedbackReport = Count(CASE WHEN v.DiscrepancyType IN (2,5) THEN v.DiscrepancyStatus END)

,Perc = 
CAST(100 - ISNULL(CAST((Count(CASE WHEN v.DiscrepancyType IN (2,5) THEN v.DiscrepancyType END) * 1.0 / Count(CASE WHEN v.ReportStandard NOT IN (0,9) THEN v.ReportStandard END)) * 100 AS FLOAT),0) AS NUMERIC(10,2))  


,VisitAssignmentID_with_FeedbackRpt = STUFF (( SELECT  ', ' + CAST(v2.AssignmentID  AS VARCHAR) from Visits v2
INNER JOIN 
Assignments a2 ON a2.AssignmentID = v2.AssignmentID
WHERE 
DATENAME(MONTH,v.VisitDate) = DATENAME(MONTH,v2.VisitDate) 
AND a2.ClientID IN (22,33) AND v2.DiscrepancyType IN (2,5)  
GROUP BY V2.AssignmentID 
FOR xml path('')), 1, 2, '')
FROM Visits v
INNER JOIN Assignments a ON a.AssignmentID = v.AssignmentID  
WHERE a.ClientID IN (22,33)
AND v.VisitDate BETWEEN '01/01/2013' AND '31/12/2013'

GROUP BY DATENAME(MONTH,v.VisitDate) 

ORDER BY MONTH_NUMBER 

结果

enter image description here

我试图简化和优化的第二个查询(但查询结果不一样)

我试图优化查询并尝试简单地查询内部查询,但我没有得到我想要的结果。它减少了总执行时间,但结果并不相同。

  WITH ALL_CTE(MONTH_NUMBER,VisitMonth,VisitID,AssignmentID,ReportStandard,DiscrepancyStatus,DiscrepancyType,VisitA     ssignmentID_with_FeedbackRpt)
 AS
 -- Define the CTE query.

(
SELECT 
    MONTH('1' + LEFT(Datename(month,visitDate),3) +'00') AS MONTH_NUMBER ,
    VisitMonth = LEFT(Datename(month,visitDate),3)
   ,v.VisitID, v.AssignmentID ,  v.ReportStandard , v.DiscrepancyStatus, v.DiscrepancyType 

     ,VisitAssignmentID_with_FeedbackRpt = 
     STUFF (( SELECT  ', ' + CAST((CASE WHEN DiscrepancyType IN (2,5) THEN v.AssignmentID END)  AS VARCHAR)                 
            FOR xml path('')), 1, 2, '')

FROM Visits v
INNER JOIN Assignments a ON a.AssignmentID = v.AssignmentID
WHERE a.ClientID IN (22,33)
AND v.VisitDate BETWEEN '01/01/2013' AND '31/12/2013'
group by v.AssignmentID,visitDate,VisitID,ReportStandard,DiscrepancyStatus,DiscrepancyType

 )
-- Define the outer query referencing the CTE name.

SELECT 
MONTH_NUMBER
,VisitMonth  
,COUNT(VisitID) 
,TotalVisits_with_StandardReport = COUNT(CASE WHEN ReportStandard NOT IN (0,9) THEN  ReportStandard END)
,TotalVisits_with_FeedbackReport = COUNT(CASE WHEN DiscrepancyType IN (2,5) THEN DiscrepancyStatus END)

,isnull(VisitAssignmentID_with_FeedbackRpt,0)   
FROM ALL_CTE

GROUP BY MONTH_NUMBER,VisitMonth,VisitAssignmentID_with_FeedbackRpt

enter image description here

客户统计信息

enter image description here

1 个答案:

答案 0 :(得分:0)

我认为你可以在这里做的唯一真正的优化就是确保你在AssignmentID上有一个索引,这样内连接就会更快。所有其他部分都非常无关紧要,它们只是在内存中处理的转换。