Giải phóng bảng máy chủ SQL không sử dụng


11

Tôi có một bảng trong SQL Server 2012 Express với nhiều không gian chưa sử dụng.

Tôi cần giải phóng không gian trong cơ sở dữ liệu.

| TÊN | ROWS | ĐẶT CH | | DỮ LIỆU | INDEX_SIZE | UNUSED |
| ------------- | -------- | -------------- | ----------- --- | ------------ | -------------- |
| Tên MyTable | 158890 | 8928296 KB | 5760944 KB | 2248 KB | 3165104 KB |

Làm cách nào để có được SQL để phát hành 3165104KB?

Tôi đã thử:

Alter table MyTableName Rebuild
DBCC CLEANTABLE (MyDbName,"MyTableName ", 0)
ALTER INDEX ALL ON MyTableName REORGANIZE ; 
ALTER INDEX PK_Image ON MyTableName REBUILD WITH (ONLINE = OFF) 

Đây là bảng:

CREATE TABLE [dbo].[MyTableName](
    [ImageID] [int] IDENTITY(1,1) NOT NULL,
    [DateScan] [datetime] NULL,
    [ScanImage] [image] NULL,
 CONSTRAINT [PK_Image] PRIMARY KEY CLUSTERED 
(
    [ImageID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, 
    ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 100) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

Điều duy nhất chúng tôi đã làm được thay thế ScanImagetrên mỗi hàng bằng một hình ảnh nhỏ hơn nhiều (đây là cách có quá nhiều không gian không sử dụng).

Câu trả lời:


10

Điều duy nhất chúng tôi đã làm được thay thế ScanImagetrên mỗi hàng bằng một hình ảnh nhỏ hơn nhiều (đây là cách có quá nhiều không gian chưa sử dụng)

Từ việc thực hiện một số thử nghiệm, phương pháp hiệu quả nhất về không gian sẽ là bỏ đơn vị phân bổ và sao chép lại (nếu bạn có cửa sổ bảo trì để thực hiện việc này).

Mã ví dụ đạt được mức giảm không gian tốt nhất cho tôi với cấu trúc bảng trong câu hỏi là:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

SET XACT_ABORT ON;

BEGIN TRAN

SELECT [ImageID],
       [ScanImage]
INTO   #Temp
FROM   [dbo].[MyTableName]

ALTER TABLE [dbo].[MyTableName]
  DROP COLUMN [ScanImage]

/*Allocation unit not removed until after this*/
ALTER INDEX PK_Image ON MyTableName REBUILD

ALTER TABLE [dbo].[MyTableName]
  ADD [ScanImage] IMAGE NULL

UPDATE [dbo].[MyTableName]
SET    [ScanImage] = T.[ScanImage]
FROM   [dbo].[MyTableName] M
       JOIN #Temp T
         ON M.ImageID = T.[ImageID]

DROP TABLE #Temp

COMMIT 

Tất cả mọi thứ là trong một giao dịch vì vậy nếu máy gặp sự cố, nó sẽ được khôi phục. Có thể có thể làm với một số xử lý lỗi hoặc ít nhất SET XACT_ABORT ON. Tôi đã sử dụng SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;để ngăn chặn bất kỳ sửa đổi đồng thời xảy ra trong hoặc sau khi sao chép và bị mất.

Số lượng trang LOB được bảo lưu sau khi giảm kích thước của một imagetrong tất cả các hàng như sau:

+ ------------------------------------------------- - + --------------------- + ------------------------- +
| Sự kiện | lob_use_page_count | lob_reserved_page_count |
+ ------------------------------------------------- - + --------------------- + ------------------------- +
| Chèn 10.000 hàng với dữ liệu 100.000 byte mỗi | 135005 | 135017 |
| Cập nhật tất cả các hàng thành dữ liệu hình ảnh 10.000 byte | 31251 | 135012 |
| Sắp xếp lại | 23687 | 25629 |
| Thả và thêm lại dữ liệu hình ảnh | 13485 | 13361 |
+ ------------------------------------------------- - + --------------------- + ------------------------- +

1
Hoặc nếu bảng lớn thì BCP hết dữ liệu và sau đó BULK INSERT trở lại - trong cửa sổ bảo trì.
Kin Shah

6

Thử

ALTER INDEX PK_Image ON MyTableName REBUILD WITH (ONLINE = OFF)

Điều này tạo lại chỉ mục được nhóm, vì vậy bạn sẽ cần thêm chỗ trong cơ sở dữ liệu của mình để hoàn thành thao tác. Nếu bạn không có thêm phòng vì đĩa của bạn đã đầy, bạn có thể thêm tệp dữ liệu mới vào cơ sở dữ liệu (trên một đĩa khác) và di chuyển bảng vào đó.

Cũng có thể chỉ mục được nhóm được xác định bằng FILLFACTOR nhỏ hơn 100%. Ví dụ, có hệ số điền được đặt thành 66%, sẽ để trống 1/3 mỗi trang dữ liệu để sử dụng trong tương lai. Nếu đây là vấn đề bạn có thể sửa đổi hệ số điền bằng cách sử dụngALTER INDEX PK_Image ON MyTableName REBUILD WITH (ONLINE = OFF, FILLFACTOR=100)

Nếu gần đây bạn đã bỏ trường có chiều dài thay đổi khỏi bảng, bạn cũng có thể thử DBCC CLEANTABLE( Databasename, "MyTableName")

Sách trực tuyến (BOL) có một bài viết tuyệt vời về việc xây dựng lại các chỉ mục tại http://technet.microsoft.com/en-us/l Library / ms188388% 28v = sql.100% 29.aspx


2

Hãy chắc chắn rằng chế độ phục hồi DB là SIMPLE.

thay đổi cột như VARBINARY(MAX).

Sau đó thử sao chép dữ liệu vào một bảng hoàn toàn mới.

Kiểm tra kích thước bảng mới bằng cách sử dụng sp_spaceused "tablename". Nếu bạn hài lòng với không gian chưa sử dụng của bảng, thì hãy kiểm tra không gian chưa sử dụng của cơ sở dữ liệu bằng cách sử dụng cùng một lệnh mà không chỉ định tên bảng. Không gian đó vẫn nằm trong các tệp cơ sở dữ liệu và không được phát hành cho HĐH.

Bạn có thể bỏ bảng gốc và đổi tên bảng mới hoặc thực hiện lại thao tác tương tự và sử dụng tên bảng gốc nếu bạn không tin tưởng đổi tên hoạt động, (tôi hoàn toàn không tin tưởng).

Nếu điều này hoạt động thì bước cuối cùng thật dễ dàng: Bạn biết cách thu nhỏ tệp và giải phóng không gian không sử dụng.

Nếu có bất kỳ khóa ngoại nào, hãy ghi lại định nghĩa của chúng, bỏ chúng, thực hiện các tác vụ tôi đã đề cập ở trên và tạo lại các khóa ngoại sau đó. Tất nhiên điều này sẽ mất thời gian và thao tác này nên được thực hiện trong thời gian nghỉ. Toàn bộ nhiệm vụ này có thể được thực hiện thông qua kịch bản cũng như để cho nó chạy qua đêm.


1

Tôi sẽ chỉ tạo một cơ sở dữ liệu mới và sao chép dữ liệu vào nó. Bạn sẽ có thể sử dụng trình hướng dẫn nhập / xuất. (Rõ ràng là một bản sao lưu và khôi phục sẽ giữ được vấn đề.) Kiểm tra kết quả nhập dữ liệu. Nếu tất cả có vẻ tốt, hãy đổi tên cơ sở dữ liệu gốc và sau đó đổi tên cơ sở dữ liệu mới thành tên bạn muốn sử dụng. (Tôi luôn đợi một chút trước khi bỏ bản gốc, chỉ để kiểm tra trực tuyến.)

Đối với những gì đáng giá, chúng tôi cũng đã lấy lại không gian blob từ cơ sở dữ liệu, nếu chúng không quá lớn, bằng các bước sau. (Tuy nhiên, vì bạn đang sử dụng SQL Server Express, bạn có thể không có chỗ để thử điều này.)

  1. Thêm một tập tin mới vào filegroup.
  2. Chạy đi DBCC SHRINKFILE(file, EMPTYFILE). Vì bạn đang thu hẹp MDF, cuối cùng nó sẽ thất bại, vì siêu dữ liệu hệ thống không thể được di chuyển. Tuy nhiên, phân bổ blob trống không được di chuyển.
  3. Chạy đi DBCC SHRINKFILE(newfile,EMPTYFILE). Điều này sẽ di chuyển dữ liệu trở lại, trừ đi không gian thừa.
  4. Thả tệp mới (bây giờ trống) từ filegroup.

Điều này giúp loại bỏ sự phình to. Tôi nên đề cập rằng chúng tôi đã sử dụng kỹ thuật này chủ yếu để tạo ra một cơ sở dữ liệu hầu như trống rỗng để thử nghiệm các kịch bản nâng cấp.


-1

Sắp xếp lại chỉ mục được nhóm - người ta có dữ liệu tại các nút, vì vậy .... nó có khả năng bị phân mảnh.


Tôi đã thử chạy: ALTER INDEX ALL ON [MyTableName] REORGANIZE;
DermFbler

3
Xây dựng lại nó;) Không tổ chức lại.
TomTom
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.