Мне нужно вставить 1,3 миллиона записей из одного стола в другой, и это занимает очень много времени (более 13 минут). После некоторых исследований я обнаружил, что лучше сделать эту операцию в партии, так что я собрал что-то вроде этого (фактический запрос более сложен, он упрощен здесь краткости):TSQL Пакетная вставка - математика не работает
DECLARE @key INT; SET @key = 0;
CREATE TABLE #CURRENT_KEYS(KEY INT)
WHILE 1=1
BEGIN
-- Getting subset of keys
INSERT INTO #CURRENT_KEYS(KEY)
SELECT TOP 100000 KEY FROM #ALL_KEYS WHERE KEY > @key
IF @@ROWCOUNT = 0 BREAK
-- Main Insert
INSERT INTO #RESULT(KEY, VALUE)
SELECT MAIN_TABLE.KEY, MAIN_TABLE.VALUE
FROM MAIN_TABLE INNER_JOIN #CURRENT_KEYS
ON MAIN_TABLE.KEY = #CURRENT_KEYS.KEY
SELECT @key = MAX(KEY) FROM #CURRENT_KEYS
TRUNCATE TABLE #CURRENT_KEYS
END
Я уже проиндексирован список из 1,3 миллиона ключей в таблице #ALL_KEYS, поэтому идея здесь находится в цикле, создавая меньшую подмножество ключей для JOIN и INSERT. Вышеуказанный цикл выполняется 13 раз (1 300 000 записей/100 000 записей в партии). Если я сделаю паузу только после одной итерации - время выполнения составляет 9 секунд. Я предположил, что общее время выполнения будет 9 * 13 секунд, но это же самое, что за 13 минут!
Любая идея, почему?
ПРИМЕЧАНИЕ. Вместо таблицы temp #CURRENT_KEYS я попытался использовать CTE, но с тем же результатом.
ОБНОВЛЕНИЕ Некоторые статистики ожиданий.
Я показываю для этого процесса PAGEIOLATCH_SH
, а иногда PREEMPTIVE_OS_WRITEFILEGATHER
в состоянии ожидания иногда более 500 мс, но часто < 100Ms. Также SP_WHO показывает пользователя как suspended
на время запроса.
ли вы измеряете какие статы подождать и посмотреть, что занимает 13 минут? Может быть автозагрузкой журнала, файла данных tempdb, блокировки, кто знает? –
@AaronBertrand Не совсем уверен, как это сделать, я не администратор базы данных и мало опыта в оптимизации –
Вы [можете найти это полезное чтение] (http://www.sqlperformance.com/2013/03/io-subsystem/кусок удаляет). Или кто-то, кого вы нанимаете, у кого есть опыт в оптимизации. :-) Вы пытались использовать транзакции внутри цикла? –