We have a SQL Server 2008 database with a table containing more than 1.4 billion records. Due to adjustments of the coordinate system, we have to expand the datatype of the coordinate column from decimal(18, 2)
to decimal(18, 3)
.
We've tried multiple things but everything resulted in an exception (transactionlog is full) after about 14 hours of execution.
These are the things we tried:
Alter Table
ALTER TABLE Adress ALTER COLUMN Coordinate decimal(18, 3) NULL
Designer
Tools > Options > Designer > Prevent saving changes that require table re-creation
decimal(18, 3)
Right-click > Generate Change Script...
What this script does, is creating a new table with the new datatype, copying the old data to the new table, drop the old table and rename the new table.
Unfortunately both attempts result in a transaction log full exception after 14 hours of execution.
I thought, that changing the datatype via ALTER TABLE... ALTER COLUMN...
is only changing the metadata and should be finished in the matter of (milli)seconds?
Thanks in advance
Well the main issue seems large amount of data saved into the table. Your both attempts also seem fine. They both will definitely take time I must say as the data is large.
Each time you alter a column data type the SQL SERVER tries to convert existing data into targeted data type. Processing the conversion on large amount of data may cause delay in execution.
Moreover I wonder if you have any trigger on the table.?
Well! Finally I would suggest you following steps. Give it a try at least
Last Point I should add is your database transaction log is also full which can be shrunk but with some precautions. Here is very good example how to reset your transaction log. Should take a look at this too.
Hope This Helps. :)
The solution is to do the updates in batches, easing the pressure on the log file.
Method 1:
a) Create a new table with the new definition.
b) Copy the data to the new table in batches.
c) Drop the old table.
d) Rename the new table.
Method 2:
a) Create a new column with the correct definition.
b) Update the new column with data from the old column in batches.
c) Drop the old column.
d) Rename the new column.
Method 3:
a) BCP the data into a file.
b) Truncate the table.
c) Alter the column.
d) Set the recovery model to bulk logged or simple.
e) BCP the data from the file into the table.
f) Set the recovery model back to full.
That is my suggestion: ADD a field to your table and name it like below:
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
Try to keep your transaction like small.
And Finaly drop your Coordinate field.
Add new column as the last column
If you try to insert before the last column it could take a long time
NewCoordinate decimal(18, 3) NULL
select 1
while(@@rowcount > 0)
BEGIN
UPDATE TOP(10000) Adress
SET NewCoordinate = Coordinate
WHERE NewCoordinate <> Coordinate
END
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.