周末我从SQLServer2000升级到了2008。现在,一个查询运行速度非常慢(大约50行的查询时间超过30秒)。
SELECT TOP 200 AccData.SurName + ', ' + AccData.FirstNames AS Name,
DATEDIFF(day, COALESCE (AccData.DateReceived, AccData.DateOpened,
AccData.InjuryDate),
GETDATE()) AS Duration, AccData.M46No, Clients.ClientName,
AccData.HomePhone, AccData.WorkPhone, AccData.InjuryDate,
AccData.ClaimID,
luClaimStatus.Meaning AS Status, AccData.Claim,
vw_LastMedCert.Fitness, vw_LastMedCert.UntilDate
FROM AccData INNER JOIN
Clients ON AccData.ClientID = Clients.ID
INNER JOIN
luClaimStatus ON AccData.ClaimStatus = luClaimStatus.ClaimStatus
LEFT OUTER JOIN
vw_LastMedCert ON AccData.Claim = vw_LastMedCert.Claim
WHERE AccData.ClientID>1 and CaseManagerId = :CaseManagerID
and (DateClosed is null or AccData.ClaimStatus ='R')
order by Surname, FirstNames
这个问题与LastMedCert有关
ALTER VIEW [dbo].[vw_LastMedCert] WITH SCHEMABINDING
AS
SELECT Claim, ClaimId, ReferralID, FromDate, UntilDate, Fitness, DateSeen,
DateEntered, PeriodFor
FROM dbo.Med_cert
WHERE (ReferralID IN
(SELECT MAX(ReferralID) AS MaxOfReferralID
FROM dbo.Med_cert AS Med_cert_1
WHERE (Fitness IS NOT NULL)
GROUP BY Claim))
有什么想法吗?我已经重建了索引并更新了统计数据
执行计划是:
|--Compute Scalar(DEFINE:([Expr1020]=datediff(day,[Expr1024],getdate())))
|--Nested Loops(Left Outer Join, OUTER REFERENCES:([CmsDB].[dbo].[AccData].[Claim]))
|--Nested Loops(Inner Join, OUTER REFERENCES:([CmsDB].[dbo].[AccData].[ClientID]))
| |--Nested Loops(Inner Join, OUTER REFERENCES:([CmsDB].[dbo].[AccData].[ClaimStatus]))
| | |--Compute Scalar(DEFINE:([Expr1019]=((([CmsDB].[dbo].[AccData].[SurName]+', ')+[CmsDB].[dbo].[AccData].[FirstNames])+' ')+CASE WHEN [CmsDB].[dbo].[AccData].[MiddleNames] IS NOT NULL THEN [CmsDB].[dbo].[AccData].[MiddleNames] ELSE '' END, [Expr1024]=CASE WHEN [CmsDB].[dbo].[AccData].[DateReceived] IS NOT NULL THEN [CmsDB].[dbo].[AccData].[DateReceived] ELSE CASE WHEN [CmsDB].[dbo].[AccData].[DateOpened] IS NOT NULL THEN [CmsDB].[dbo].[AccData].[DateOpened] ELSE [CmsDB].[dbo].[AccData].[InjuryDate] END END))
| | | |--Nested Loops(Inner Join, OUTER REFERENCES:([Uniq1002], [CmsDB].[dbo].[AccData].[Claim], [CmsDB].[dbo].[AccData].[SurName], [CmsDB].[dbo].[AccData].[FirstNames], [Expr1027]) WITH ORDERED PREFETCH)
| | | |--Index Seek(OBJECT:([CmsDB].[dbo].[AccData].[IX_AccData_ByCaseManagerId]), SEEK:([CmsDB].[dbo].[AccData].[CaseManagerID]=(100346)) ORDERED FORWARD)
| | | |--Clustered Index Seek(OBJECT:([CmsDB].[dbo].[AccData].[byName]), SEEK:([CmsDB].[dbo].[AccData].[SurName]=[CmsDB].[dbo].[AccData].[SurName] AND [CmsDB].[dbo].[AccData].[FirstNames]=[CmsDB].[dbo].[AccData].[FirstNames] AND [CmsDB].[dbo].[AccData].[Claim]=[CmsDB].[dbo].[AccData].[Claim] AND [Uniq1002]=[Uniq1002]), WHERE:([CmsDB].[dbo].[AccData].[ClientID]>(1) AND ([CmsDB].[dbo].[AccData].[DateClosed] IS NULL OR [CmsDB].[dbo].[AccData].[ClaimStatus]='R')) LOOKUP ORDERED FORWARD)
| | |--Clustered Index Seek(OBJECT:([CmsDB].[dbo].[luClaimStatus].[PK_luClaimStatus_1__172]), SEEK:([CmsDB].[dbo].[luClaimStatus].[ClaimStatus]=[CmsDB].[dbo].[AccData].[ClaimStatus]) ORDERED FORWARD)
| |--Index Seek(OBJECT:([CmsDB].[dbo].[Clients].[PK_Clients_2__13]), SEEK:([CmsDB].[dbo].[Clients].[ID]=[CmsDB].[dbo].[AccData].[ClientID]), WHERE:([CmsDB].[dbo].[Clients].[ID]>(1)) ORDERED FORWARD)
|--Nested Loops(Inner Join, WHERE:([Expr1018]=[CmsDB].[dbo].[Med_cert].[ReferralID]))
|--Clustered Index Seek(OBJECT:([CmsDB].[dbo].[Med_cert].[byClaim]), SEEK:([CmsDB].[dbo].[Med_cert].[Claim]=[CmsDB].[dbo].[AccData].[Claim]) ORDERED FORWARD)
|--Table Spool
|--Stream Aggregate(GROUP BY:([CmsDB].[dbo].[Med_cert].[Claim]) DEFINE:([Expr1018]=MAX([CmsDB].[dbo].[Med_cert].[ReferralID])))
|--Clustered Index Scan(OBJECT:([CmsDB].[dbo].[Med_cert].[byClaim]), WHERE:([CmsDB].[dbo].[Med_cert].[Fitness] IS NOT NULL) ORDERED FORWARD)
我通过重写初始查询解决了这个问题。它现在运行大约1秒钟,但我仍然想知道出了什么问题,这样如果它再次出现,我就可以修复它。
初始查询运行时间约为2分钟,具体取决于参数。按照验证计划和dm_db_missing_index_details建议添加索引,将运行时间减少到大约4秒。
添加哈希提示将运行时间减少到2秒。
决定接受哪个答案是一个艰难的决定,大多数答案都提供了一些帮助。