【问题标题】:How to Optimize this query (stuff part)如何优化这个查询(东西部分)
【发布时间】:2014-01-28 17:34:50
【问题描述】:

如何优化以下查询:

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 

结果

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

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

  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

客户统计

【问题讨论】:

  • 请您发布您的执行计划
  • 我已经添加了客户端统计信息,您要我添加执行计划吗?
  • 请。执行计划会告诉我们问题出在哪里,可以做图片也可以做xml

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


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 2012-12-22
    • 1970-01-01
    • 2013-03-01
    • 2021-01-27
    • 2010-11-15
    相关资源
    最近更新 更多