Apakah ada cara untuk mengubah tipe data kolom sebagai operasi metadata saja?
Saya rasa tidak, inilah cara kerja produk saat ini. Ada beberapa solusi yang sangat bagus untuk batasan yang diusulkan dalam jawaban Joe ini .
... hasil dalam SQL Server menulis ulang seluruh tabel (dan menggunakan ukuran tabel 2x dalam ruang log)
Saya akan menanggapi dua bagian dari pernyataan itu secara terpisah.
Menulis Ulang Meja
Seperti yang saya sebutkan sebelumnya, sebenarnya tidak ada cara untuk menghindari ini. Itu tampaknya menjadi kenyataan dari situasi itu, bahkan jika itu tidak masuk akal sepenuhnya dari perspektif kita sebagai pelanggan.
Melihat DBCC PAGE
sebelum dan sesudah mengubah kolom dari 4000 menjadi 260 menunjukkan bahwa semua data diduplikasi pada halaman data (tabel pengujian saya memiliki 'A'
260 kali berturut-turut):
Pada titik ini, ada dua salinan data yang sama persis di halaman. Kolom "lama" pada dasarnya dihapus (id diubah dari id = 2 menjadi id = 67108865), dan versi "baru" kolom diperbarui untuk menunjuk ke offset baru dari data pada halaman:
Menggunakan 2x Tabel Ukuran dalam Ruang Log
Menambahkan WITH (ONLINE = ON)
ke akhir ALTER
pernyataan mengurangi aktivitas logging sekitar setengahnya , jadi ini adalah satu peningkatan yang dapat Anda lakukan untuk mengurangi jumlah penulisan ke disk / ruang disk yang dibutuhkan.
Saya menggunakan test harness ini untuk mencobanya:
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
Saya memeriksa sys.dm_io_virtual_file_stats(DB_ID(N'248749'), DEFAULT)
sebelum dan sesudah menjalankan ALTER
pernyataan, dan berikut ini perbedaannya:
Default (Offline) ALTER
- File data ditulis / byte ditulis: 34.809 / 2.193.801.216
- File log menulis / byte yang ditulis: 40.953 / 1.484.910.080
On line ALTER
- File data ditulis / byte ditulis: 36.874 / 1.693.745.152 (turun 22,8%)
- File log menulis / byte ditulis: 24.680 / 866.166.272 (41% turun)
Seperti yang Anda lihat, ada sedikit penurunan pada file data tulis, dan penurunan besar dalam file log menulis.