Есть только несколько вещей, которые могут происходить, и хитрость здесь в том, чтобы устранить их по порядку, от самого простого до самого сложного.
ШАГ 1: Ручная обработка набора XML для запускаэто произведет ровно одну вставку без обновлений, так что вы можете вернуться к основам и установить, что код все еще выполняет то, что вы ожидаете, и результат в точности соответствует вашим ожиданиям.Это может показаться глупым или ненужным, но вам действительно нужна эта проверка реальности для начала.
ШАГ 2: Сделайте вручную набор XML, который произведет набор вставок среднего размера, но без обновлений.Исходя из вашего опыта с рутиной, попробуйте найти что-то, что будет работать в течение 3-4 секунд.Возможно, 5000 строк.Это продолжает вести себя как ожидалось?
ШАГ 3: Предполагая, что шаги 1 и 2 проходят легко, следующая наиболее вероятная проблема - РАЗМЕР СДЕЛКИ.Если ваше обновление достигает 74 000 строк в одном операторе, то SQL Server должен выделить ресурсы, чтобы иметь возможность откатить все 74 000 строк в случае сбоя.Как правило, вы должны предполагать, что ресурсы (и время), необходимые для поддержания транзакции, растут в геометрической прогрессии по мере увеличения числа строк.Итак, сделайте вручную еще один набор вставок, который содержит 50 000 строк.Вы должны найти, что это занимает значительно больше времени.Пусть это закончится.Это 10 минут, час?Если это занимает много времени, но завершается, у вас есть проблема с размером транзакции, сервер задыхается, пытаясь отследить все необходимое для отката вставки в случае сбоя.
ШАГ 4: Определите, еслився ваша хранимая процедура работает в рамках одной подразумеваемой транзакции.Если это так, то дело обстоит еще хуже, потому что SQL Server отслеживает все, что требуется для отката как 74 000 обновлений, так и ???вставляет в одну транзакцию.Смотрите эту страницу:
http://msdn.microsoft.com/en-us/library/ms687099(v=vs.85).aspx
ШАГ 5: Если у вас есть одна неявная транзакция, вы можете сделать это либо.A) Отключите это, что может помочь некоторым, но не решит проблему полностью, или B) разбить спрок на два отдельных вызова, один для обновлений, один для вставок, так что по крайней мере два находятся в отдельных транзакциях.
ШАГ 6: Подумайте над "кусками".Это метод, позволяющий избежать взрыва транзакционных издержек.Рассматривая только INSERT, чтобы начать нас, вы помещаете вставку в цикл, который начинает и фиксирует транзакцию внутри каждой итерации и завершается, когда количество затронутых строк равно нулю.INSERT изменен таким образом, что вы извлекаете только первые 1000 строк из источника и вставляете их (число 1000 является произвольным, может оказаться, что 5000 дает лучшую производительность, вам придется немного поэкспериментировать).Как только INSERT воздействует на нулевые строки, больше нет строк, которые нужно обработать, и цикл завершается.
БЫСТРОЕ РЕДАКТИРОВАНИЕ: Система «чанкинга» работает, потому что полная пропускная способность для большого набора строк выглядит как квадратичная.Если вы выполняете INSERT, который влияет на огромное количество строк, общее время обработки всех строк увеличивается.Если, с другой стороны, вы разбиваете его и идете строка за строкой, накладные расходы, связанные с открытием и фиксацией каждого оператора, приводят к общему времени взрыва всех строк.Где-то посередине, когда вы «разбили» по 1 тыс. Строк на оператор, требования к транзакциям минимальны, а издержки на открытие и фиксацию оператора незначительны, а общее время обработки всех строк минимально..