Чи є спосіб змінити тип даних стовпця як операцію, що стосується лише метаданих?
Я не думаю, що цей продукт працює зараз. Існує кілька дійсно чудових вирішень цього обмеження, запропонованого у відповіді Джо .
... призводить до того, що SQL Server переписав всю таблицю (та використовував 2x розмір таблиці в просторі журналу)
Я збираюся відповісти на дві частини цієї заяви окремо.
Переписування таблиці
Як я вже згадував, насправді немає жодного способу цього уникнути. Це здається реальністю ситуації, навіть якщо це не має повного сенсу з нашої точки зору як клієнтів.
Якщо дивитися на DBCC PAGE
зміну стовпця з 4000 на 260, видно, що всі дані дублюються на сторінці даних (у моїй тестовій таблиці було 'A'
260 разів підряд):
На даний момент на сторінці є дві копії абсолютно однакових даних. "Старий" стовпчик по суті видаляється (ідентифікатор змінено з id = 2 на id = 67108865), а "нова" версія стовпця оновлюється, щоб вказувати на нове зміщення даних на сторінці:
Використання 2x Розмір таблиці в просторі журналу
Додавання WITH (ONLINE = ON)
до кінця ALTER
оператора зменшує активність ведення журналу приблизно вдвічі , тому це одне вдосконалення, яке ви можете зробити, щоб зменшити кількість запису на диск / місце на диску.
Я використовував цей тестовий джгут, щоб спробувати його:
USE [master];
GO
DROP DATABASE IF EXISTS [248749];
GO
CREATE DATABASE [248749]
ON PRIMARY
(
NAME = N'248749',
FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL14.SQL2017\MSSQL\DATA\248749.mdf',
SIZE = 2048000KB,
FILEGROWTH = 65536KB
)
LOG ON
(
NAME = N'248749_log',
FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL14.SQL2017\MSSQL\DATA\248749_log.ldf',
SIZE = 2048000KB,
FILEGROWTH = 65536KB
);
GO
USE [248749];
GO
CREATE TABLE dbo.[table]
(
id int IDENTITY(1,1) NOT NULL,
[col] nvarchar (4000) NULL,
CONSTRAINT [PK_test] PRIMARY KEY CLUSTERED (id ASC)
);
INSERT INTO dbo.[table]
SELECT TOP (1000000)
REPLICATE(N'A', 260)
FROM master.dbo.spt_values v1
CROSS JOIN master.dbo.spt_values v2
CROSS JOIN master.dbo.spt_values v3;
GO
Я перевірив sys.dm_io_virtual_file_stats(DB_ID(N'248749'), DEFAULT)
до і після запуску ALTER
оператора, і ось які відмінності:
За замовчуванням (офлайн) ALTER
- Запис / байт даних у файл даних: 34,809 / 2,193,801,216
- Записані файли / байти журналу: 40,953 / 1,484,910,080
Інтернет ALTER
- Записані файли даних / байтів: 36 874 / 1,693,745,152 (падіння на 22,8%)
- Записані записи / байти журналу: 24,680 / 866,166,272 (падіння на 41%)
Як ви бачите, у записі файлу даних було незначне падіння, а у файлі журналу - велике падіння.