Назад | Перейти на главную страницу

Как ускорить добавление столбца в большую таблицу на сервере Sql

Я хочу добавить столбец в таблицу Sql Server примерно с 10 миллионами строк. Я думаю, что этот запрос в конце концов завершите добавление нужного столбца:

alter table T
add mycol bit not null default 0

но это идет уже несколько часов. Есть ли какой-либо ярлык для вставки столбца «не нулевое значение по умолчанию 0» в большую таблицу? Или это действительно очень медленно?

Это Sql Server 2000. Позже мне придется сделать что-то подобное на Sql Server 2008.

Хм, 10 миллионов строк - это довольно мало, но это не выходит за рамки MSSQL и кажется очень медленным.

У нас была таблица с огромным размером строки (плохо спроектированная) и более чем 10 миллионами строк. Когда нам пришлось изменить структуру, это была деф. очень медленно, поэтому мы сделали следующее (чтобы таблица оставалась в сети, и это грубо по памяти, потому что это было давным-давно):

  • Создана новая таблица с суффиксом "C" (для преобразования) и новой структурой (т.е. такая же, как старая, но с новым столбцом / индексом / и т. Д.)
  • ВЫБРАТЬ * В таблицуC ИЗ таблицы
  • sp_rename 'table' tableOld '
  • sp_rename 'tableC' table '

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

В зависимости от размера вашей строки, размера таблицы, индексов и т. Д. Я видел, как SQL Server 2000 работал несколько часов (4-5 часов), прежде чем НАКОНЕЦ завершился.

Худшее, что вы можете сделать прямо сейчас, - это «паниковать» и сильно убить тварь. Пусть само исчерпается.

В будущем вы можете попробовать сделать то, что упоминал Farseeker, и создать вторую (пустую) структуру и скопировать свои записи таким образом.

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

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

Удачи! :-)

Вы можете попробовать выполнить каждый шаг операции в отдельном пакете, например

alter table T add mycol bit null
go
update T set mycol = 0
go
alter table T alter column mycol bit not null
go
alter table T add default 0 for mycol
go

Преимущества:

  • Вы получите лучшую обратную связь о ходе операции, так как теперь это 4 отдельные партии, каждая из которых занимает примерно 1/4 времени.
  • Это снижает вероятность ошибок тайм-аута при запуске из клиентского кода.
  • Я считаю, что иногда это улучшает производительность.

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

Это займет некоторое время. Это потому, что вы добавляете значение по умолчанию. Это заставляет SQL Server обновлять все строки за одну транзакцию. Убедитесь, что никто другой не использует эту таблицу, так как это приведет к блокировке вашего процесса.

Я проделал то же самое в таблице, содержащей не менее 65 миллионов строк, и это не заняло так много времени. Достаточно ли памяти и достаточно ли производительности в дисковой системе

Если вы хотите ускорить процесс, вы можете удалить все индексы, за исключением ограничений кластеризованного индекса и внешнего ключа, прежде чем изменять таблицу, но это нужно делать, когда система не используется, иначе вы можете получить несовместимые данные. Но, в конце концов, вам нужно будет применить внешние ключи и индексы до того, как вы закончите, но вы облегчите боль для журнала транзакций, по крайней мере, если вы запустите простую модель восстановления. А в SQL Server 2008 вы можете создавать индексы с ONLINE = on и SORT_IN_TEMPDB = on

Хокан Винтер

На самом деле вы не собираетесь сокращать что-то вроде этого - независимо от того, что вы делаете, SQL Server придется выполнять некоторую обработку для всех строк в таблице.

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

Часы для 10-метровых рядов - это слишком много. Убедитесь, что на столе ничто не удерживает замки открытыми.

На одном учебном курсе я поговорил с парой администраторов баз данных из Министерства обороны. Они управляют базами данных MySQL размером 100 ТБ и более. Изменения таблицы выполняются с помощью дампа и загрузки, но это, очевидно, требует некоторого времени простоя. Они также упомянули, что им не нравится делать это с базами данных размером более 10 ТБ из-за затраченного времени.

Данные выгружены, они не указали, что делать, но я бы предположил, что файлы SQL. Затем таблицы усекаются, а схема изменяется по мере необходимости. Затем данные перезагружаются.

У вас было несколько индексов для вашей таблицы, и может даже быть кластерный индекс для вашей таблицы T?

У меня также возникла проблема с добавлением нового столбца (это столбец идентичности). В таблице было 9,3 миллиона строк, и у нее есть один некластеризованный индекс по первичному ключу.

По какой-то причине, если мы отбросить индекс для таблицы T, затем добавьте столбец, а затем снова добавьте индекс для таблицы T. Это было в основном в 60 раз быстрее на Standard SQLServer 2008.

Я не понял, почему он так ускорился, надеюсь, кто-нибудь ответит мне на это.