开发者

T-SQL 2 versions of the same query: Why one runs in 10 seconds, the other in 206 seconds (table variable vs subquery)

The relevant schema for this database is there are Jobs which have Job Phases which have DailyInfos. I wrote a function that takes the DailyInfoID and returns a bunch of data related to that Daily. The idea is that if I want Job Phase To Date values, I would call the function for every DailyInfo in that JobPhase by using cross apply on a query that returns all the DailyInfoIDs for that JobPhase. This works well on the JobPhase level.

Now when I go to the Job level, the query runs MUCH slower. Let's say there are 5 phases in a job, if I run the Job Phase to Date query 5 times for each Job Phase, it runs in a reasonable amount of time. However if I run the first Job To Date query below, it takes MUCH longer. The second version of the query, which uses a table variable instead of a subquery, takes the correct amount of time (ie the sum of the 5 Job Phase To Date queries). Why does the table variable version take so much less time and # rea开发者_如何转开发ds than the subquery version?

Version 1 - Duration: 210,225ms CPU: 206,203ms Reads: 38,737,658

SELECT
    di.DailyInfoID,
    DailyCycleTimes.NetHaulCY,
    DailyCycleTimes.PayCY,
    DailyCycleTimes.DigCY,
    DailyCycleTimes.FillCY,

    DailyCycleTimes.DelayMinutes,
    DailyCycleTimes.PumpMinutes,
    DailyCycleTimes.TurnMinutes,
    DailyCycleTimes.SailToMinutes,
    DailyCycleTimes.SailFromMinutes,
    DailyCycleTimes.ConnectMinutes,
    DailyCycleTimes.DisconnectMinutes,
    DailyCycleTimes.DischargeMinutes
FROM
(
    SELECT di.DailyInfoID
    FROM DailyInfo di
    INNER JOIN JobPhase jp ON jp.JobPhaseID = di.JobPhaseID
    INNER JOIN Job j ON j.JobID = jp.JobID
    WHERE j.JobID = @JobID
)di
CROSS APPLY calc.fGetDailyCycleTimes(di.DailyInfoID) DailyCycleTimes

Version 2 - Duration: 9,654 CPU: 9,593 Reads: 2,039,088

DECLARE @DailyInfo table(DailyInfoID int)

INSERT INTO @DailyInfo
SELECT di.DailyInfoID
FROM DailyInfo di
INNER JOIN JobPhase jp ON jp.JobPhaseID = di.JobPhaseID
INNER JOIN Job j ON j.JobID = jp.JobID
WHERE j.JobID = @JobID

SELECT  
    di.DailyInfoID,
    DailyCycleTimes.NetHaulCY,
    DailyCycleTimes.PayCY,
    DailyCycleTimes.DigCY,
    DailyCycleTimes.FillCY,

    DailyCycleTimes.DelayMinutes,
    DailyCycleTimes.PumpMinutes,
    DailyCycleTimes.TurnMinutes,
    DailyCycleTimes.SailToMinutes,
    DailyCycleTimes.SailFromMinutes,
    DailyCycleTimes.ConnectMinutes,
    DailyCycleTimes.DisconnectMinutes,
    DailyCycleTimes.DischargeMinutes
FROM @DailyInfo di
CROSS APPLY calc.fGetDailyCycleTimes(di.DailyInfoID) DailyCycleTimes


Check the actual execution plan for each in Management Studio - that will tell you where the cost is attributed for each.


The table variable can't be optimized by the query engine, where the underlying table (when used directly) can.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜