查询优化 - 建议?

时间:2015-03-08 21:18:06

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

我希望有人可以帮助我理解这个XML Showplan以获得长时间运行的查询。此查询来自软件供应商开发的Crystal Report,运行速度非常慢,我正在尝试将其转换为SSRS报告,同时加快查询速度。

以下是Execution Plan - File Dropper上托管的文件的链接。

这是实际的查询本身:

Select Distinct
CD.desclong [Center],
CD.CenterType,
Sub.Description [SubCenter],
Org.Description [OrgCenter],
CO.CodeID [CenterC],
Sub.CodeID [SubCenterC],
Org.CodeID [OrgCenterC],
Reg.Description [Region],
Reg.CodeID [RegionC],
Rec.CodeID [RecID], 
Rec.Description [RecName],
Rec.NickName [RecNickName],
Acct.AccountID [AcctCharCode],
DM.DriveID,
DM.ExternalID [DriveExtID],
DM.FromDateTime [DriveDate],
dbo.getShiftProductProjectionList(DSD.shiftid)  [ProductProjections], 
dbo.getShiftProcedureProjectionList(DSD.shiftid)  [ProcedureProjections], 
dbo.getShiftMobileList(DSD.shiftid, '1,2,3') [MobileSetups],
LD.LocationName [LocationName],

Case DM.OwnerType
   When 1 Then FSM.DisplayName
   When 0 Then Acct.InternalName 
End [OwnerName], Acct.ExternalID [AcctExtID], SM.ExternalID [SiteExtID],

Stat.StatusText [DriveStatus],
DSD.ShiftID,
DSD.ShiftStart,
DSD.ShiftEnd,
DT.EarlyShiftStart,
DT.LateShiftEnd,
Changes.*,
dbo.getOriginalProcedureProjection(Changes.dsprocshiftid, Changes.dsprocprocedureid) [OriginalProjection], 
(Select Top 1 DescMed From Production.[dbo].QuickCodes where CodeValue = 'ACTEXTIDTAG') [ActExtIDTag],
(Select Top 1 DescMed From Production.[dbo].QuickCodes where CodeValue = 'SITEEXTIDTAG') [SiteExtIDTag],
(Select Top 1 DescMed From Production.[dbo].QuickCodes where CodeValue = 'DRVEXTIDTAG') [DrvExtIDTag],

Case When (Changes.TableName = 'DriveShiftProcedureDetail') Then (Select Top 1 projectionid From driveshiftproceduredetail where uniquekey = Changes.owneruniquekey) else null end as ProjectionID

From
Production.[dbo].rpt_DriveMaster DM
Join Production.[dbo].rpt_DriveShiftDetail DSD on DSD.DriveID = DM.DriveID
Join Production.[dbo].CriticalDriveChanges Changes on (Changes.SourceDriveID = DM.DriveID and Changes.SourceShiftID = DSD.ShiftID and
    Production.[dbo].returnDateTime(year(Changes.ChangeWhen),month(Changes.ChangeWhen),day(Changes.ChangeWhen)) between '01/04/2015' and '01/04/2015')

And
    (
        (
        (Changes.TableName='DriveShiftProcedureDetail' and Changes.ColumnName='projection')
        or 
        (Changes.TableName='DriveShiftDetail' and (Changes.ColumnName='ShiftStart' or Changes.ColumnName='ShiftEnd'))
        or 
        (Changes.TableName='DriveShiftDetail' and Changes.ColumnName='StaffRequested')
        or 
        (Changes.TableName='DriveShiftDetail' and Changes.changetype='Delete')
        or 
        (Changes.TableName='DriveMaster' and Changes.ColumnName='StatusID' and Changes.NewValue='5')
        or 
        (Changes.TableName='DriveMaster' and Changes.ColumnName='FromDateTime')
        or
        (Changes.TableName='DriveShiftRoleTimeDetail' and Changes.ColumnName='Lead')
        or
        (Changes.TableName='DriveShiftRoleTimeDetail' and Changes.ColumnName='TravelTo')
        or
        (Changes.TableName='DriveShiftRoleTimeDetail' and Changes.ColumnName='Setup')
        or
        (Changes.TableName='DriveShiftRoleTimeDetail' and Changes.ColumnName='Breakdown')
        or
        (Changes.TableName='DriveShiftRoleTimeDetail' and Changes.ColumnName='TravelFrom')
        or
        (Changes.TableName='DriveShiftRoleTimeDetail' and Changes.ColumnName='WrapUp')
    )
        and
        (Changes.ChangeWho<>'RMADMIN')
)

Join Production.[dbo].rpt_DriveStatusDef Stat on Stat.StatusID = DM.StatusID
Join Production.[dbo].DriveTimes DT on DT.DriveID = DM.DriveID
Left Outer Join Production.[dbo].rpt_CenterDetail CD on CD.CenterID = DM.centerid
Left Outer Join Production.[dbo].IDViewRegion Reg on CD.Region = Reg.CodeID
Left Outer Join Production.[dbo].IDViewOrgCenter Org on CD.OrgCenter = Org.CodeID
Left Outer Join Production.[dbo].IDViewOrgSubCenter Sub on CD.OrgSubcenter = Sub.CodeID
Left Outer Join Production.[dbo].IDViewCollectionOp CO on cd.centerid = CO.CodeID
Left Outer Join Production.[dbo].IDViewRecruiter Rec on Rec.CodeID = DM.RecruiterID
Left Outer Join Production.[dbo].rpt_Accounts Acct on Acct.AccountID = DM.AccountID
Left Outer Join Production.[dbo].rpt_FixedSiteScheduleMaster FSM on FSM.DrawID = DM.DrawID
Left Outer Join Production.[dbo].rpt_LocationDetail LD on LD.LocationID = DM.LocationID
Join Production.[dbo].rpt_SiteMaster SM on SM.SiteID = DM.SiteID

Where 
(dbo.returnDateTime(year(DM.Fromdatetime),month(DM.Fromdatetime),day(DM.Fromdatetime)) between '01/04/2015' and '01/04/2015')
or     (dbo.returnDateTime(year(Changes.previousdrivedate),month(Changes.previousdrivedate),day(Changes.previousdrivedate)) between '01/04/2015' and '01/04/2015')

以下是使用Set Statistics XML On

的实际执行计划

Execution Plan

谢谢!

我删除了returnDateTime的函数,并使用了以下代码:

-- In the FROM statement
Join Hemasphere_Dev.[dbo].CriticalDriveChanges Changes on (Changes.SourceDriveID = DM.DriveID And Changes.SourceShiftID = DSD.ShiftID And Changes.ChangeWhen Between '01/01/2015' And '01/15/2015')
    --Hemasphere_Dev.[dbo].returnDateTime(year(Changes.ChangeWhen),month(Changes.ChangeWhen),day(Changes.ChangeWhen)) between '01/01/2015' And '01/15/2015')


-- In the WHERE statement
DM.FromDateTime Between '01/01/2015' And '01/15/2015'
Or Changes.PreviousDriveDate Between '01/01/2015' and '01/15/2015'
--(dbo.returnDateTime(year(DM.FromDateTime),month(DM.FromDateTime),day(DM.FromDateTime)) Between '01/01/2015' And '01/15/2015')
--Or (dbo.returnDateTime(year(Changes.previousdrivedate),month(Changes.previousdrivedate),day(Changes.previousdrivedate)) Between '01/01/2015' And '01/15/2015')

查询实际上以这种方式运行得很慢。

0 个答案:

没有答案
相关问题