Из всего, что я вижу, не похоже, что ваши проблемы связаны с индексами.
Ключ, кажется, заключается в том, что ваше поле nvarchar (max) содержит «много» данных. Подумайте, что SQL должен сделать, чтобы выполнить это обновление.
Поскольку столбец, который вы обновляете, вероятно, содержит более 8000 символов, он хранится за пределами страницы, что подразумевает дополнительные усилия при чтении этого столбца, когда он не является NULL.
Когда вы запускаете пакет из 50000 обновлений, SQL должен поместить его в неявную транзакцию, чтобы можно было откатить в случае каких-либо проблем. Чтобы откат назад, он должен сохранить исходное значение столбца в журнале транзакций.
Предполагая (для простоты), что каждый столбец содержит в среднем 10 000 байт данных, то есть 50 000 строк будут содержать около 500 МБ данных, которые необходимо временно хранить (в режиме простого восстановления) или постоянно (при полном восстановлении) Режим).
Невозможно отключить журналы, поскольку это приведет к нарушению целостности базы данных.
Я проверил быструю проверку своего рабочего стола на медленном рабочем столе, а запущенные партии даже на 10 000 стали заведомо медленными, но при этом размер до 1000 строк, что подразумевает временный размер журнала около 10 МБ, работал просто красиво.
Я загрузил таблицу с 350 000 строк и отметил 50 000 из них для обновления. Это завершено примерно за 4 минуты, и поскольку он линейно масштабируется, вы сможете обновить все свои 5 миллионов рядов на моем медленном рабочем столе моей собаки примерно за 6 часов на моем 1-процессорном рабочем столе на 2 ГБ, поэтому я бы ожидал чего-то гораздо лучшего на вашем усиленном сервере SAN или что-то в этом роде.
Возможно, вы захотите запустить инструкцию по обновлению в качестве выбора, выбрав только первичный ключ и большой столбец nvarchar, и убедитесь, что это выполняется так быстро, как вы ожидаете.
Конечно, узким местом могут быть другие пользователи, блокирующие вещи или конфликты на вашем хранилище или памяти на сервере, но поскольку вы не упомянули других пользователей, я предполагаю, что для этого у вас есть БД в однопользовательском режиме.
В качестве оптимизации вы должны обеспечить, чтобы журналы транзакций находились на другой группе физического диска/диска, чем данные, чтобы минимизировать время поиска.
См. Также: http://stackoverflow.com/questions/571750/make-sql-server-faster-at-manipulating-data-turn-off-transaction-logging –
Как вы делаете «50 тыс. Партийных записей в время "обновления? Это с хранимой процедурой? Если да, можете ли вы поместить код? – Fede
@ user356004: при повторном чтении я не могу не думать о том, что ваш сервер находится под большой нагрузкой или он настроен неправильно: эти времена кажутся очень высокими. –