SQL Server, преобразование NTEXT в NVARCHAR (MAX) - PullRequest
10 голосов
/ 28 января 2009

У меня есть база данных с большим количеством полей, которые в настоящее время являются NTEXT.

После обновления до SQL 2005 мы выполнили несколько тестов производительности при преобразовании их в NVARCHAR (MAX).

Если вы читаете эту статью:

http://geekswithblogs.net/johnsPerfBlog/archive/2008/04/16/ntext-vs-nvarcharmax-in-sql-2005.aspx

Это объясняет, что простая ALTER COLUMN не реорганизует данные в строки.

Я испытываю это с моими данными. На самом деле у нас гораздо хуже в некоторых областях, если мы просто запускаем ALTER COLUMN. Однако, если я запускаю таблицу UPDATE SET SET Column = Column для всех этих полей, мы получим чрезвычайно большое повышение производительности.

У меня проблема в том, что база данных состоит из сотен этих столбцов с миллионами записей. Простой тест (на виртуальной машине с низкой производительностью) имел таблицу с одним столбцом NTEXT, содержащим 7 миллионов записей, для обновления потребовалось 5 часов.

Кто-нибудь может предложить какие-либо предложения относительно того, как я могу обновить данные более эффективным способом, который минимизирует время простоя и блокировки?

РЕДАКТИРОВАТЬ: Мое решение для резервного копирования - просто обновлять данные в блоках с течением времени, однако, с нашими данными это приводит к ухудшению производительности, пока все записи не будут обновлены, и чем короче это время, тем лучше, поэтому я все еще ищу для более быстрого способа обновления.

Ответы [ 5 ]

6 голосов
/ 28 января 2009

Если вы не можете получить запланированное время простоя ....

создайте две новые колонки: NVARCHAR (макс) обработанный флаг INT DEFAULT 0

Создать некластеризованный индекс для обработанного флага

Вам доступен UPDATE TOP (вы хотите обновить топ, упорядоченный по первичному ключу).

Просто установите флаг обработки в 1 во время обновления, чтобы следующее обновление обновлялось только тогда, когда флаг обработки все еще равен 0

.

Вы можете использовать @@ rowcount после обновления, чтобы увидеть, можно ли выйти из цикла.

Я предлагаю использовать WAITFOR в течение нескольких секунд после каждого запроса на обновление, чтобы дать другим запросам возможность получить блокировки таблицы и не перегружать использование диска.

3 голосов
/ 28 января 2009

Если вы можете получить запланированное время простоя:

  1. Резервное копирование базы данных
  2. Изменить модель восстановления на простую
  3. Удалить все индексы из таблицы, которую вы обновляете
  4. Добавить флаг обслуживания столбца (INT DEFAULT 0) с некластеризованным индексом
  5. Пробег: ОБНОВЛЕНИЕ ТОП 1000 имя_таблицы SET nvarchar от ntext, флаг обслуживания = 1 ГДЕ флаг обслуживания = 0

Требуется несколько раз (в цикле с задержкой).

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

Помните, что каждый индекс или триггер в этой таблице вызывает дополнительный дисковый ввод-вывод и что простой режим восстановления минимизирует ввод-вывод лог-файла.

3 голосов
/ 28 января 2009

Как насчет запуска обновления в пакетном режиме - обновлять 1000 строк одновременно.

Вы бы использовали цикл while, который увеличивает счетчик, соответствующий идентификатору строк, которые будут обновляться на каждой итерации запроса на обновление. Это может не ускорить время, необходимое для обновления всех 7 миллионов записей, но значительно снизит вероятность того, что пользователи столкнутся с ошибкой из-за блокировки записи.

1 голос
/ 28 января 2009

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

0 голосов
/ 28 января 2009

Вы также можете подумать о том, чтобы проверить, может ли пакет служб SSIS сделать это более эффективно.

Что бы вы ни делали, сделайте это автоматизированным процессом, который можно запланировать и запустить в нерабочее время. чем меньше пользователей будет пытаться получить доступ к данным, тем быстрее все пойдет. Если это вообще возможно, выберите три или четыре наиболее важных для изменения и отключите базу данных для обслуживания (в течение обычно нерабочего времени) и выполните их в однопользовательском режиме. Как только вы получите самые важные, другие могут быть назначены один или два на ночь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...