Запрос работает плохо, если временная таблица не используется - PullRequest
1 голос
/ 09 июня 2010

Следующий запрос выполняется около 1 минуты и имеет следующую статистику ввода-вывода:

SELECT T.RGN, T.CD, T.FUND_CD, T.TRDT, SUM(T2.UNITS) AS TotalUnits
FROM dbo.TRANS AS T
JOIN dbo.TRANS AS T2 ON T2.RGN=T.RGN AND T2.CD=T.CD AND T2.FUND_CD=T.FUND_CD AND T2.TRDT<=T.TRDT
JOIN TASK_REQUESTS AS T3 ON T3.CD=T.CD AND T3.RGN=T.RGN AND T3.TASK = 'UPDATE_MEM_BAL'
GROUP BY T.RGN, T.CD, T.FUND_CD, T.TRDT

(затронуто 4447 строк) Таблица «СДЕЛКИ». Сканирование счетчика 5977, логическое чтение 7527408, физическое чтение 0, чтение с опережением 0, логическое чтение с бита 0, физическое чтение с бита 0, чтение с опережением чтения 0. Таблица «TASK_REQUESTS». Сканирование 1, логическое чтение 11, физическое чтение 0, чтение с опережением 0, логическое чтение с 0, физическое чтение с 0, чтение с опережением 0.

Время выполнения SQL Server: Время ЦП = 58157 мс, прошедшее время = 61437 мс

Если вместо этого я ввожу временную таблицу, запрос быстро возвращается и выполняет меньше логических операций чтения:

CREATE TABLE #MyTable(RGN VARCHAR(20) NOT NULL, CD VARCHAR(20) NOT NULL, PRIMARY KEY([RGN],[CD]));
INSERT INTO #MyTable(RGN, CD) SELECT RGN, CD FROM TASK_REQUESTS WHERE TASK='UPDATE_MEM_BAL';

SELECT T.RGN, T.CD, T.FUND_CD, T.TRDT, SUM(T2.UNITS) AS TotalUnits
FROM dbo.TRANS AS T
JOIN dbo.TRANS AS T2 ON T2.RGN=T.RGN AND T2.CD=T.CD AND T2.FUND_CD=T.FUND_CD AND T2.TRDT<=T.TRDT
JOIN #MyTable AS T3 ON T3.CD=T.CD AND T3.RGN=T.RGN
GROUP BY T.RGN, T.CD, T.FUND_CD, T.TRDT

(затронуто 4447 строк) Стол «Рабочий стол». Сканирование счетчика 5974, логическое чтение 382339, физическое чтение 0, чтение с опережением 0, логическое чтение 1, физическое чтение 1, чтение с опережением 0. Таблица «СДЕЛКИ». Сканирование 4, логическое чтение 4547, физическое чтение 0, чтение с опережением 0, логическое чтение с 0, физическое чтение с 0, чтение с опережением 0. Таблица «#MyTable ____________________________________________________________________________________________________________ 000000000013». Сканирование 1, логическое чтение 2, физическое чтение 0, чтение с опережением 0, логическое чтение с 0, физическое чтение с 0, чтение с опережением 0.

Время выполнения SQL Server: Время ЦП = 1420 мс, прошедшее время = 1515 мс.

Для меня интересно то, что таблица TASK_REQUEST - это небольшая таблица (в настоящее время 3 строки), и статистика в таблице обновлена. Любая идея, почему такие разные планы выполнения и время выполнения будет происходить? И в идеале, как изменить ситуацию, чтобы мне не нужно было использовать временную таблицу для достижения достойной производительности?

Единственное реальное различие в планах выполнения заключается в том, что в версии временной таблицы вводится операция спулинга индекса (eager spool).

Ответы [ 3 ]

1 голос
/ 09 июня 2010

Вы делаете сравнение строк для каждой строки. Версия временной таблицы не учитывает это сравнение. Сравнение строк не особенно быстрое, и это было бы первым, на что я бы посчитал источником дополнительных вычислительных затрат.

0 голосов
/ 09 июня 2010
;WITH MyTable AS
( 
    SELECT RGN, CD FROM TASK_REQUESTS WHERE TASK = 'UPDATE_MEM_BAL'
)
SELECT t.RGN, t.CD, t.FUND_CD, t.TRDT, SUM(t2.UNITS) [TotalUnits]
FROM dbo.TRANS t
JOIN dbo.TRANS t2 ON (t2.RGN = t.RGN 
                  AND t2.CD = t.CD 
                  AND t2.FUND_CD = t.FUND_CD 
                  AND t2.TRDT <= t.TRDT)
JOIN MyTable t3 ON (t3.CD = t.CD AND t3.RGN = t.RGN)
GROUP BY t.RGN, t.CD, t.FUND_CD, t.TRDT
0 голосов
/ 09 июня 2010

Это просто любопытство, у меня нет особых оснований полагать, что это будет быстрее, но вы пробовали:

SELECT T.RGN, T.CD, T.FUND_CD, T.TRDT, SUM(T2.UNITS) AS TotalUnits 
FROM dbo.TRANS AS T 
JOIN dbo.TRANS AS T2 ON T2.RGN=T.RGN AND T2.CD=T.CD AND T2.FUND_CD=T.FUND_CD AND T2.TRDT<=T.TRDT 
JOIN TASK_REQUESTS AS T3 ON T3.CD=T.CD AND T3.RGN=T.RGN     
WHERE T3.TASK = 'UPDATE_MEM_BAL' 
GROUP BY T.RGN, T.CD, T.FUND_CD, T.TRDT 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...