部分查询的高 I/O

Ala*_*n T 7 performance sql-server-2005 execution-plan query-performance performance-tuning

我有一个很大的查询要调整。我写了很多查询,但没有做很多调整。我已经包含了 SQL Sentry Plan Explorer Free (SSPEF) 的屏幕截图:

高输入/输出

在计划的上述部分中,表 pb_WorkRquestLog 包含 229,001 行。但是,查询计划显示大约。3.48 亿行(229,001 x 1,520 次迭代):

在此处输入图片说明

没有 where 子句,因此查询使用的是聚集索引扫描。我已经用 FULLSCAN 重建了所有索引并更新了所有统计信息。

这部分计划正在执行的代码是:

select distinct 
            wrs.ServiceKey 
            , owner.DepartmentName AS GroupName
            , owner.UserName AS UserId
            , owner.WRLCreateDateTime
            , owner.WRLNotes
            , wrx.CreatedDate as WRCreateDateTime
            , wrx.Id
            , wrx.Description 
            , cast(wrx.Notes as varchar(2500)) as Notes
        from    
            prism72ext.dbo.pb_WorkRequestService wrs 
            Join prism72ext.dbo.pb_WorkRequest wrx on (wrs.WorkRequestId = wrx.Id and wrx.Status = 'Incomplete')
            left join (
                select
                    wl.WorkRequestId
                    ,   d.Name AS DepartmentName
                    ,   u.UserName
                    , wl.CreatedDate as WRLCreateDateTime
                    , cast(wl.Notes as varchar(2500)) as WRLNotes
                from
                    (
                        SELECT     
                            MAX( Id ) AS Id
                        FROM          
                                prism72ext.dbo.pb_WorkRequestLog WITH(INDEX(0))
                        GROUP BY 
                            WorkRequestId
                    ) mwl
                    join prism72ext.dbo.pb_WorkRequestLog wl on mwl.Id = wl.Id
                    join prism72Ext.dbo.pb_Department d ON wl.DepartmentId = d.DepartmentId
                    left join prism72Ext.dbo.pb_User u on wl.UserId = u.UserId
                ) owner on wrs.WorkRequestId = owner.WorkRequestId
Run Code Online (Sandbox Code Playgroud)

SSPEF 报告实际数据大小接近 5GB,具有 300 万次逻辑读取!SSMS 报告该表的大小仅为 16 MB。

我已将查询从 4 分 28 秒调整为 1 分 35 秒,但现在我卡住了。如果有人能指出我处理这个问题的正确方向,我将不胜感激。

编辑:有人建议尝试“OPTION (HASH JOIN, MERGE JOIN)”。这产生了巨大的差异。I/O 大幅减少,查询运行时间为 13 秒。

有没有人看到这个解决方案有任何问题?

小智 1

如果您还没有,请创建一个复合非聚集索引prism72ext.dbo.pb_WorkRequestLog(WorkRequestId, Id DESC)并在没有索引提示的情况下运行查询。

另外,让派生表的内部选择owner返回mwl.WorkRequestId而不是ml.WorkRequestId.