Версии T-SQL 2 для одного и того же запроса: почему один выполняется за 10 секунд, другой - за 206 секунд (переменная таблицы и подзапрос) - PullRequest
2 голосов
/ 08 ноября 2010

Соответствующей схемой для этой базы данных являются рабочие места с фазами заданий, в которых есть DailyInfos. Я написал функцию, которая берет DailyInfoID и возвращает кучу данных, связанных с этим Daily. Идея состоит в том, что если мне нужны значения Job Phase To Date, я бы вызвал функцию для каждого DailyInfo в этом JobPhase, используя перекрестное применение к запросу, который возвращает все DailyInfoID для этого JobPhase. Это хорошо работает на уровне JobPhase.

Теперь, когда я перехожу на уровень заданий, запрос выполняется НАМНОГО медленнее. Допустим, в задании есть 5 этапов, и если я запускаю запрос «От этапа к дате» 5 раз для каждого этапа задания, он выполняется за разумное время. Однако, если я выполню первый запрос Job To Date ниже, это займет НАМНОГО дольше. Вторая версия запроса, в которой вместо подзапроса используется переменная таблицы, занимает правильное количество времени (т. Е. Сумма 5 запросов фазы выполнения задания). Почему версия табличной переменной занимает намного меньше времени и чтения #, чем версия подзапроса?

Версия 1 - Продолжительность: 210 225 мс Процессор: 206 203 мс Число операций чтения: 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

Версия 2 - Продолжительность: 9 654 Процессор: 9 593 Чтения: 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

Ответы [ 2 ]

1 голос
/ 08 ноября 2010

Переменная таблицы не может быть оптимизирована механизмом запросов, где базовая таблица (при непосредственном использовании) может.

1 голос
/ 08 ноября 2010

Проверьте фактический план выполнения для каждого в Management Studio - в нем будет указано, где указана стоимость для каждого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...