SQL Server 2005表假脱机(懒惰假脱机) - 性能

Arb*_*æde 5 sql sql-server-2005

我有一些遗留SQL(SP)

  declare @FactorCollectionId       int;        select  @FactorCollectionId = collectionID from dbo.collection where name = 'Factor'
    declare @changeDate             datetime;   set @changeDate = getDate()
    declare @changeTimeID           int;        set @changeTImeID = convert(int, convert(varchar(8), @changeDate, 112))
    declare @MaxWindowID            int;        select @MaxWindowID = MAX(windowID) from dbo.window

  select distinct @FactorCollectionId, ElementId, T.TimeID, @changeTimeId ChangeTimeID, 1 UserID, @MaxWindowID, 0 ChangeID
                            , null TransactionID, SystemSourceID, changeTypeID, 'R' OlapStatus, Comment, Net0 Delta0, Net0
                            , 1 CreatedBy, 1 UpdatedBy, @changeDate CreatedDate, @changeDate UpdatedDate, 1 CurrentRecord, MeasureTypeID
                from dbo.aowCollectedFact FV
                    inner join dbo.timeView T on T.timeID >= FV.timeID
                where FV.currentRecord = 1                              --is current record
                    and T.CurrentHorizon <> 0                           --Indicator that Time is part of current horizon
                    and FV.collectionID = @FactorCollectionId           --factor collections only
                    and FV.timeID = (select  MAX(timeID)                --latest collected fact timeID for given collectionID and elementID
                                        from    aowCollectedFact FV2
                                        where   FV2.collectionId = @FactorCollectionId
                                            and FV2.elementId = FV.elementID)
                    and (((T.ForecastLevel = 'Month') and (T.FirstDayInMonth = T.Date))     --Date is first of month for monthly customers, or
                            or 
                        ((T.ForecastLevel = 'Quarter')and (T.FirstDayInQuarter = T.Date)))  --Date is first of quarter for quarterly customers
                    and not exists (select  1                                               --Record does not already exist in collected fact view
                                    from    aowCollectedFact FV3                            --  for this factor collection, elementID, and timeID
                                    where   FV3.collectionId = @FactorCollectionId
                                        and FV3.elementID = FV.elementId
                                        and FV3.timeID = T.timeID)
Run Code Online (Sandbox Code Playgroud)

此SQL处理超过200万行.我需要提高它的性能.当我查看执行计划时,我发现在Table Spool (Lazy spool)操作上花费了大量时间(表中存在索引并且它们运行良好).

如何提高这部分的性能?

Nic*_*aro 9

在看到执行计划或表索引之前,我会给出最好的教育猜测.首先,这里有几个值得一读的链接.

本周的showplan运算符 - 懒惰的线轴

表盘/懒惰阀芯

索引:查看您的索引以确保它们全部覆盖您从表中选择的列.您将希望获得索引中的JOIN和WHERE子句中包含的所有列.SELECT语句中的所有其他列应该由索引包含或覆盖.

运算符:看看你是否可以摆脱不等于("<>")运算符,而不是单个大于或小于运算符.这个陈述and T.CurrentHorizon <> 0可以改为这个and T.CurrentHorizon > 0吗?

JOINS:摆脱加入自身之外的表的子查询.例如,这一行and FV2.elementId = FV.elementID可能会导致一些问题.dbo.aowCollectedFact FV鉴于您已在主查询中进行GROUPing(DISTINCT),因此没有理由不能将其移出子查询并转换为JOIN .

DISTINCT:将其更改为GROUP BY.我没有其他理由,因为这是一个很好的做法,需要两分钟.

最后注意:上述所有异常可能是将最终子查询IF NOT EXISTS(作为子查询)保留.如果将其更改为JOIN,则必须是一个LEFT JOIN...WHERE NULL语句,这实际上可能导致假脱机操作.没办法绕过那个.