Il modo migliore per ridurre un DB dopo l'annullamento dei dati da varbinary (max)?


8

Abbiamo un database con una grande quantità di dati memorizzati in un campo di tipo varbinary (max) . Ad un certo punto possiamo eliminare quei dati per la maggior parte delle righe, ma non per tutti. Il nostro piano è di rendere quel campo nulla e di annullare semplicemente i dati quando non sono più necessari. Una volta fatto ciò, vorremmo ridurre le dimensioni del DB. Qual è il modo migliore per raggiungere questo obiettivo?

Se non c'è un buon modo per recuperare spazio con la configurazione corrente, un'idea che ho è quella di spostare quel campo di dati in una tabella separata con solo due colonne: la chiave per la tabella principale e il campo di dati. Quindi potremmo semplicemente eliminare le righe quando non sono più necessarie. (E poi fare una sorta di restringimento.) Tuttavia, questo sarebbe un cambiamento molto più difficile da apportare che semplicemente rendere nulla il campo esistente.

Nota: in realtà non mi interessa molto rendere il file di database più piccolo, ma mi interessa che lo spazio appena liberato diventi riutilizzabile.

Oltre il 90% delle dimensioni del DB è questo campo. Sono già a 3 TB.

Risposte:


13

Mi sembra che solo l'aggiornamento delle colonne NULLrilascerà le pagine per il riutilizzo. Ecco una demo di Very Scottish®, per festeggiare che è quasi alle 17:00, 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);

Con le righe inserite, controlliamo sulle nostre pagine indice.

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;

Dopo l'inserimento, ottengo questo. Le pagine effettive possono variare per te.

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

Usciamo NULLalcune file!

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

E torna alle nostre pagine:

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

Quindi il conteggio delle pagine è stato ridotto. Huzzah! Per i due indici che toccano i nostri VARBINARYdati, hanno perso una pagina buncha. Ciò significa che sono di nuovo in circolazione per altri oggetti da utilizzare. Dato che sono in tempdb, probabilmente vengono inghiottiti abbastanza rapidamente da tutte le cose spazzatura che succedono qui.

Ora reinseriamo alcuni dati:

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

E ricontrollare:

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

La pagina conta un po 'alzata.

Quindi, sembra che non devi fare nulla di troppo folle, o addirittura ridurre il database per riutilizzare lo spazio. Penso DBCC CLEANTABLEche tu stia confondendo il comportamento di far cadere le colonne e aver bisogno di correre con quello che stai effettivamente facendo.

Spero che sia di aiuto!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.