Cách tốt nhất để thu nhỏ DB sau khi hủy dữ liệu từ varbinary (max)?


8

Chúng tôi có một cơ sở dữ liệu với một lượng lớn dữ liệu được lưu trữ trong một trường kiểu varbinary (max) . Tại một số điểm, chúng tôi có thể lọc dữ liệu đó cho hầu hết các hàng, nhưng không phải tất cả. Kế hoạch của chúng tôi là làm cho trường đó trở nên vô hiệu, và đơn giản là loại bỏ dữ liệu khi không còn cần thiết. Khi chúng tôi làm điều đó, chúng tôi muốn giảm kích thước của DB. cách tốt nhất để thực hiện điều này là gì?

Nếu không có cách nào tốt để lấy lại không gian với thiết lập hiện tại, một ý tưởng tôi có là di chuyển trường dữ liệu đó sang một bảng riêng biệt chỉ với hai cột: khóa vào bảng chính và trường dữ liệu. Sau đó, chúng ta có thể xóa các hàng khi chúng không còn cần thiết nữa. (Và sau đó thực hiện một số loại thu nhỏ.) Tuy nhiên, đây sẽ là một thay đổi khó thực hiện hơn nhiều so với việc đơn giản làm cho trường hiện tại trở nên vô hiệu.

Lưu ý: Tôi thực sự không quan tâm lắm đến việc làm cho tệp cơ sở dữ liệu nhỏ hơn, nhưng tôi quan tâm đến không gian mới được giải phóng sẽ có thể sử dụng lại được.

Hơn 90% kích thước DB là một trường này. Tôi đã ở mức 3TB rồi.

Câu trả lời:


13

Đối với tôi, có vẻ như chỉ cần cập nhật các cột NULLsẽ phát hành các trang để sử dụng lại. Đây là bản demo Very Scottish®, để chào mừng nó đã gần 5 giờ chiều, 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);

Với các hàng được chèn, hãy kiểm tra trên các trang chỉ mục của chúng tôi.

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;

Sau khi chèn, tôi nhận được điều này. Các trang thực tế có thể khác nhau cho bạn.

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

Hãy NULLra một số hàng!

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

Và kiểm tra lại trên các trang của chúng tôi:

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

Vì vậy, số lượng trang đã giảm. Huzzah! Đối với hai chỉ mục chạm vào VARBINARYdữ liệu của chúng tôi , chúng bị mất một trang bó. Điều đó có nghĩa là chúng quay trở lại lưu hành cho các đối tượng khác sử dụng. Vì tôi đang ở trong tempdb, có lẽ họ sẽ bị nuốt chửng khá nhanh bởi tất cả những thứ rác rưởi đang diễn ra ở đây.

Bây giờ hãy đưa một số dữ liệu trở lại:

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

Và kiểm tra lại:

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

Số lượng trang nhích lên một chút.

Vì vậy, có vẻ như bạn không phải làm bất cứ điều gì quá điên rồ, hoặc thậm chí thu nhỏ cơ sở dữ liệu của bạn để sử dụng lại không gian. Tôi nghĩ rằng bạn đang nhầm lẫn hành vi thả cột và cần phải chạy DBCC CLEANTABLEvới những gì bạn đang làm.

Hi vọng điêu nay co ich!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.