Мне нужно обновить 100 миллионов записей в одной таблице, по сути, нормализуя таблицу, заменив значение столбца varchar просто идентификатором. (Я говорю «замена», но на самом деле я пишу идентификатор в другой столбец.)
Я пытаюсь добиться нормализации набора данных. Еще не нормализованные данные не имеют индексации. Я думал, что я не буду строить индексы для необработанных значений, ожидая, вместо этого индексировать внешние ключи, которые будут заменять значения varchar значениями tinyint после завершения обновления.
UPDATE A
SET A.AutoClassID = B.AutoClassID
FROM AutoDataImportStaging.dbo.Automobile as A
JOIN AutoData.dbo.AutoClass as B on (A.AutoClassName = B.AutoClassName)
Фон
- использование MSSQL 2008 R2 на сервере 2008 R2
- сервер имеет 8 ГБ оперативной памяти
- на сервере есть один RAID10, 7200 об / мин SATA (я знаю, что в производственном режиме это будет только чтение данных, а не запись данных; плюс недавний дефицит HD сделал это необходимым по стоимости)
- сервер имеет двойной четырехъядерный процессор Xeon
- машина больше ничего не делает (в данный момент посвящена dev, только этот процесс)
- включено простое ведение журнала (? - но оно все еще регистрируется, чтобы можно было выполнить откат?)
- обратите внимание, что запрос ссылается на две разные БД, для чего это стоит
- «ширина» обновляемой записи в таблице составляет 455 байт
Ресурсы во время исполнения
- физическое ОЗУ максимально
- дисковый ввод / вывод максимально
- Процессор почти ничего не делает (точка дросселирования - ввод / вывод)
- Время работы составило 14 часов и считал!
Я подозреваю несколько вещей, например, мне нужен индекс для необработанных данных, хотя я буду отбрасывать столбец (AutoClassName) после обновления нормализации. Мне также интересно, должен ли я просто зацикливать таблицу по одной записи за раз вместо JOIN, что казалось нелепым в то время, когда я начинал это, но теперь кажется, что это было бы быстрее.
Как мне изменить мою методологию для оставшихся обновлений нормализации (аналогично этой) быстрее?
источник
TOP
пункт. Это был бы мой подход.Я бы выбрал другой подход.
Вместо обновления существующих таблиц просто создайте новую таблицу, в которой есть то, что вам нужно.
Это почти наверняка будет быстрее:
В настоящее время написано много логических операций:
источник
Зацикливание таблицы по одной строке за раз, не будет быстрее!
Как вы подозреваете и подтверждаете вы, это будет связано с вводом / выводом - один диск, чтение, запись, журналы транзакций и (любое) временное рабочее пространство будут конкурировать за один и тот же ввод / вывод.
Простое восстановление по-прежнему будет регистрировать транзакции, но журнал будет очищен контрольной точкой. Вполне возможно, что исходный размер журнала и параметры автоматического увеличения вызывают некоторое замедление ввода-вывода - журнал транзакций должен будет увеличиваться, чтобы учесть изменения.
Вы пробовали индексировать поле AutoClassName? Сколько существует различных значений автокласса?
Возможно, вам придется пакетировать обновления, в зависимости от ограничений вашего ввода-вывода. Так что обнови 1 миллион, контрольно-пропускной пункт, повтори ....
источник
Создайте индексы для полей объединения.
Вы всегда можете удалить индексы, когда вы закончите.
Я был бы очень удивлен, если бы индексы не значительно улучшили производительность обновления.
источник
Экспортируйте так, как вы хотите, создайте новую таблицу и импортируйте обратно. В качестве бонуса у вас будет копия данных в качестве резервной копии на случай чудес.
источник