Почему SELECT во временную таблицу не медленнее, чем MERGE, чем просто MERGE из исходного запроса? - PullRequest
0 голосов
/ 07 ноября 2018

Вот MERGE, использующий результаты табличной функции:

MERGE
    Table1 d
USING
    dbo.tvf_Table1(@StartDate, @EndDate) s ON d.ID = s.ID
WHEN MATCHED THEN UPDATE
    SET Dest1 = Src1, Dest2 = Src2, Dest3 = Src3
WHEN NOT MATCHED THEN INSERT
    VALUES(ID, Src1, Src2, Src3);

В моей среде это заняло около 30 секунд (в среднем за три пробежки).

Вот то же самое MERGE, но на этот раз функция помещается в первую очередь во временную таблицу:

SELECT
    *
INTO
    #Temp1
FROM
    dbo.tvf_Table1(@StartDate, @EndDate)

MERGE
    Table1 d
USING
    #Temp1 s ON d.ID = s.ID
WHEN MATCHED THEN UPDATE
    SET Dest1 = Src1, Dest2 = Src2, Dest3 = Src3
WHEN NOT MATCHED THEN INSERT
    VALUES(ID, Src1, Src2, Src3);

DROP TABLE #Temp1

Это заняло около 31 секунды (в среднем за три пробежки).

На самом деле, запуск 54 MERGE, подобных описанным выше, был на четыре минуты быстрее с временными таблицами, чем без.

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

Что происходит за кулисами, которые могут вызвать это?

Ответы [ 2 ]

0 голосов
/ 07 ноября 2018

Временные таблицы дают оптимизатору больше информации для оптимизации, чем табличная функция.

Я могу оценить, что вы ожидаете, что накладные расходы на запись в таблицу замедлят процесс в целом. Однако остальная часть запроса на слияние также должна быть оптимизирована, и знание точного размера таблицы помогает оптимизатору улучшить общий план.

0 голосов
/ 07 ноября 2018

При условии, что объем данных, помещаемых во временную таблицу, не слишком велик, сервер должен иметь возможность хранить все это в памяти и не выливать его на диск. Таким образом, B в вашем A -> B, B -> C является исключительно дешевым по сравнению с C (и, возможно, A). Обычно вы ожидаете, что затраты на ввод / вывод затопят большинство других в простых запросах.

В общем, я бы все же предпочел сингл MERGE, если он работает достаточно адекватно. Не пытайтесь помочь SQL Server, разбив задачу на ряд подзадач - это работа для оптимизатора, и хотя он не всегда выбирает оптимальный план, он обычно выбирает достаточно хороший.

...