Следующий запрос выполняется около 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).