2016-06-21 9 views
2

У нас есть база данных SQL Server 2008 с таблицей, содержащей более 1,4 миллиарда записей. Из-за корректировок системы координат нам необходимо расширить тип данных координатного столбца от decimal(18, 2) до decimal(18, 3).Изменение типа данных столбца в SQL Server

Мы пробовали несколько вещей, но все закончилось исключением (транзакционный лог заполнен) примерно через 14 часов после выполнения.

Это то, что мы пытались:

  1. Alter Таблица

    ALTER TABLE Adress 
    ALTER COLUMN Coordinate decimal(18, 3) NULL 
    
  2. Дизайнер

    • Uncheck Tools > Options > Designer > Prevent saving changes that require table re-creation
    • Open Designer
    • Изменить тип данных столбца decimal(18, 3)
    • Right-click > Generate Change Script...

Что делает этот сценарий, создает новую таблицу с новым типом данных, копируя старые данные в новую таблицу, отбросить старую таблицу и переименовать новую таблицу.

К сожалению, обе попытки приводят к полному исключению журнала транзакций после 14 часов исполнения.

Я думал, что изменение типа данных через ALTER TABLE... ALTER COLUMN... изменяет только метаданные и должно быть закончено в течение (милли) секунд?

  • Вы знаете какой-либо другой метод, который я мог бы попробовать?
  • Почему мои попытки (особенно # 1) требуют много времени?

Заранее спасибо

+2

** Некоторые ** изменения для таблиц может быть выполнено только при изменении метаданных. Ни в коем случае не меняется * все *, и тот, который вы выполняете, требует обновления каждой строки. Итак, я думаю, вам нужно больше пространства журналов. –

+0

Попробуйте 'select CONVERT (двоичный код (8), CONVERT (десятичный (18,3), 1,5)), CONVERT (двоичный (8), CONVERT (десятичный (18,2), 1,5))', и вы увидите, что * представление * совершенно иное. –

+0

A. Насколько велико используемое пространство, используемое таблицей (отчеты об использовании диска)? B. И сколько дискового пространства у вас есть для вашего эксперимента? Если B> A, вы можете рассмотреть возможность создания новой таблицы с нуля и bcping-данных на нее (что может выполняться партиями и минимизировать использование журнала транзакций). В качестве побочного эффекта вы получите более компактную и менее фрагментированную организацию данных. Вы также должны использовать сжатие, если оно еще не используется – Jan

ответ

3

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

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

Кроме того, интересно, у вас есть триггер на столе.?

Хорошо! Наконец, я предлагаю вам следующие шаги. Попробуйте по крайней мере

  1. Удалите все первичные ключи/указатели/ограничения, указывающие на старый столбец, и отключите любой триггер (если таковой имеется).
  2. Внесите новый столбец с нулевым значением с новым типом данных (даже если должен быть NOT NULL) к таблице.
  3. Теперь сделайте запрос на обновление таблицы, которая установит новое значение столбца в значение старого столбца. Вы можете выполнять обновление в кусках при обновлении 1000/100000 партий записей. А также вы можете применить условия к запросу для получения лучших результатов.
  4. После обновления всех таблиц, установив новые значения столбцов старого столбца, то удалить NULL символа NOT NULL от дизайнера (если он предназначается, чтобы быть NOT NULL).
  5. Drop/Удалить старый столбец. Выполните команду «Выбрать запрос» и «Проверьте свои изменения».

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

Надеюсь, что это поможет. :)

1

Решение состоит в том, чтобы делать обновления в партиях, ослабляя давление на файл журнала.

Способ 1:
a) Создайте новую таблицу с новым определением.
b) Копирование данных в новую таблицу партиями.
c) Бросьте старый стол.
d) Переименуйте новую таблицу.

Способ 2:
a) Создайте новый столбец с правильным определением.
b) Обновите новый столбец данными из старого столбца партиями.
c) Бросьте старый столбец.
d) Переименуйте новый столбец.

Способ 3:
a) BCP данные в файл.
b) Обрезайте стол.
c) Изменить колонку.
d) Установите модель восстановления на массовый журнал или простую.
e) BCP данные из файла в таблицу.
f) Установите модель восстановления полностью.

1

Вот мое предложение: добавить поле в таблицу и назовите его, как показано ниже:

NewCoordinate DECIMAL (18, 3) NULL

WHILE(1 = 1) 
BEGIN 
    UPDATE TOP(1000) Adress SET NewCoordinate = Coordinate 
    WHERE NewCoordinate IS NULL 
     IF (@@ROWCOUNT < 1000)  
    BREAK  
END 

Старайтесь, чтобы ваши сделки, как маленький.

И окончательно отбросьте поле координат.

+0

где NewCoordinate <> Координата – Paparazzi

0

Добавить новый столбец в последней колонке
Если вы попытаетесь вставить до последнего столбца это может занять много времени
NewCoordinate десятичной (18, 3) NULL

select 1 
while(@@rowcount > 0) 
BEGIN 
    UPDATE TOP(10000) Adress 
    SET NewCoordinate = Coordinate 
    WHERE NewCoordinate <> Coordinate 
END 
Смежные вопросы