Cara terbaik untuk mengecilkan DB setelah menghapus data dari varbinary (maks)?


8

Kami memiliki database dengan sejumlah besar data yang disimpan di bidang tipe varbinary (maks) . Pada titik tertentu kita dapat membersihkan data itu untuk sebagian besar baris, tetapi tidak semua. Rencana kami adalah membuat bidang itu nullable, dan hanya membatalkan data ketika tidak diperlukan lagi. Setelah kami melakukan itu kami ingin mengurangi ukuran DB. Apa cara terbaik untuk mencapai ini?

Jika tidak ada cara yang baik untuk mendapatkan kembali ruang dengan pengaturan saat ini, satu ide yang saya miliki adalah memindahkan bidang data ke tabel terpisah hanya dengan dua kolom: kunci ke tabel utama dan bidang data. Kemudian kita bisa menghapus baris ketika mereka tidak lagi diperlukan. (Dan kemudian melakukan semacam penyusutan.) Namun, ini akan menjadi perubahan yang jauh lebih sulit untuk dibuat daripada hanya membuat bidang yang ada dapat dibatalkan.

Catatan: Saya sebenarnya tidak terlalu peduli tentang membuat file database lebih kecil, tapi saya peduli tentang ruang yang baru dibebaskan menjadi dapat digunakan kembali.

Lebih dari 90% ukuran DB adalah bidang yang satu ini. Saya sudah di 3TB.

Jawaban:


13

Sepertinya saya baru saja memperbarui kolom untuk NULLakan merilis halaman untuk digunakan kembali. Ini demo Very Scottish®, untuk merayakannya hampir jam 5 sore, EST.

USE tempdb;

DROP TABLE IF EXISTS dbo.RobertBurns;

CREATE TABLE dbo.RobertBurns
(
    Id INT IDENTITY(1, 1) PRIMARY KEY CLUSTERED,
    Scotch VARCHAR(50),
    HaggisAddress VARBINARY(MAX)
);

DECLARE @AddressToAVarbinaryHaggis VARBINARY(MAX); 
DECLARE @AddressToAHaggis NVARCHAR(MAX) = N'
Good luck to you and your honest, plump face,
Great chieftain of the pudding race!
Above them all you take your place,
        gut, stomach-lining, or intestine,
You''re well worth a grace
        as long as my arm.

The overloaded serving tray there you fill,
Your buttocks shaped like a distant hilltop,
Your wooden skewer could be used to fix a mill
         if need be,
While through your pores your juices drip
         like liquid gold.

His knife see the serving-man clean,
And then cut you up with great skill,
Making a trench in your bright, gushing guts
        To form a ditch,
And then, 0h! What a glorious sight!
        Warm, steaming, and rich!

Then, spoonful after spoonful, they eagerly eat,
The devil will get the last bit, on they go,
Until all their well-stretched stomachs, by-and-by,
        are bent like drums,
Then the head of the family, about to burst,
        murmurs “Thank the Lord".

Is there a pretentious soul who, over his French ragout,
Or Italian cuisine that would make a pig sick,
Or French stew that would make that same pig ill
        with complete and utter disgust,
Looks down with a sneering, scornful attitude,
        on such a meal? (as Haggis)

Poor devil! See him over his trash!
As feeble as a withered bullrush,
His skinny leg no thicker than a thin rope,
        His fist the size of a nut,
Through a river or field to travel,
        Completely unfit!

But look at the healthy, Haggis-fed person!
The trembling earth respects him as a man!
Put a knife in his fist,
        He''ll make it work!
And legs, and arms, and heads will come off,
        Like the tops of thistle.

You Powers who look after mankind,
And dish out his bill of fare,
Old Scotland wants no watery, wimpy stuff
        That splashes about in little wooden bowls!
But, if You will grant her a grateful prayer,
        Give her a Haggis!';


INSERT dbo.RobertBurns (Scotch, HaggisAddress )
SELECT TOP 1000 
CASE WHEN x.c % 15 = 0 THEN 'Laphroaig'
     WHEN x.c % 5 = 0 THEN 'Lagavulin'
     WHEN x.c % 3 = 0 THEN 'Port Ellen'
     ELSE 'Ardbeg'
END AS Scotch, 
CONVERT(VARBINARY(MAX), REPLICATE(@AddressToAHaggis, x.c % 20 + 1))
FROM (
SELECT ROW_NUMBER() OVER (ORDER BY @@ROWCOUNT) AS c
FROM sys.messages AS m
) AS x;

CREATE INDEX ix_novarbinary ON  dbo.RobertBurns (Scotch, Id);
CREATE INDEX ix_yesvarbinary ON dbo.RobertBurns (Scotch, Id) INCLUDE (HaggisAddress);

Dengan baris yang dimasukkan, mari kita periksa halaman indeks kami.

SELECT   OBJECT_NAME(i.object_id) AS table_name,
         i.name AS index_name,
         MAX(a.used_pages) AS leaf_me_alone
FROM     sys.indexes AS i
JOIN     sys.partitions AS p
ON p.object_id = i.object_id
   AND p.index_id = i.index_id
JOIN     sys.allocation_units AS a
ON a.container_id = p.partition_id
WHERE OBJECT_NAME(i.object_id) = 'RobertBurns'
GROUP BY i.object_id, i.index_id, i.name
ORDER BY OBJECT_NAME(i.object_id), i.index_id;

Setelah dimasukkan, saya mendapatkan ini. Halaman yang sebenarnya dapat bervariasi untuk Anda.

table_name  index_name                      leaf_me_alone
RobertBurns PK__RobertBu__3214EC074BE633A2  5587
RobertBurns ix_novarbinary                  10
RobertBurns ix_yesvarbinary                 5581

Mari kita NULLkeluar beberapa baris!

UPDATE rb
    SET rb.HaggisAddress = NULL
FROM dbo.RobertBurns AS rb
WHERE rb.Id % 15 = 0;

Dan periksa kembali di halaman kami:

table_name  index_name                      leaf_me_alone
RobertBurns PK__RobertBu__3214EC074BE633A2  5300
RobertBurns ix_novarbinary                  10
RobertBurns ix_yesvarbinary                 5273

Jadi jumlah halaman berkurang. Sabas! Untuk dua indeks yang menyentuh VARBINARYdata kami , mereka kehilangan banyak halaman. Itu berarti mereka kembali beredar untuk digunakan benda lain. Karena saya di tempdb, mereka mungkin akan menelan cukup cepat oleh semua hal-hal sampah yang terjadi di sini.

Sekarang mari kita masukkan kembali beberapa data:

INSERT dbo.RobertBurns (Scotch, HaggisAddress )
SELECT TOP 10 rb.Scotch, rb.HaggisAddress
FROM dbo.RobertBurns AS rb;

Dan memeriksa kembali:

table_name  index_name                      leaf_me_alone
RobertBurns PK__RobertBu__3214EC074BE633A2  5330
RobertBurns ix_novarbinary                  11
RobertBurns ix_yesvarbinary                 5305

Jumlah halaman sedikit meningkat.

Jadi, sepertinya Anda tidak perlu melakukan sesuatu yang terlalu gila, atau bahkan mengecilkan database Anda untuk mendapatkan ruang kembali. Saya pikir Anda menggabungkan perilaku menjatuhkan kolom dan perlu menjalankan DBCC CLEANTABLEapa yang sebenarnya Anda lakukan.

Semoga ini membantu!

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.