xây dựng lại trên chỉ mục cụm, tại sao dữ liệu thu nhỏ?


10

Khi chúng tôi thực hiện xây dựng lại một chỉ mục được nhóm trên một bảng có khoảng 15gb dữ liệu trong đó và dữ liệu được thu nhỏ thành 5gb, làm thế nào điều này có thể? Những loại "dữ liệu" được loại bỏ?

Kích thước dữ liệu tôi có nghĩa là cột "dữ liệu" của DBCC sp_spaceuse

Trước khi Rebuild trên chỉ mục cụm:

name                  rows        reserved    data        index_size  unused
LEDGERJOURNALTRANS    43583730    39169656 KB 15857960 KB 22916496 KB 395200 KB

Sau khi xây dựng lại trên chỉ mục cụm:

name                  rows        reserved    data        index_size  unused
LEDGERJOURNALTRANS    43583730    29076736 KB 5867048 KB  22880144 KB 329544 KB

TSQL để xây dựng lại:

USE [DAX5TEST]
GO
ALTER INDEX [I_212RECID] ON [dbo].[LEDGERJOURNALTRANS] REBUILD PARTITION = ALL WITH ( PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, ONLINE = ON, SORT_IN_TEMPDB = OFF, DATA_COMPRESSION = PAGE, FILLFACTOR = 85 )
GO

Bạn đang xác định kích thước dữ liệu từ kích thước tập tin?
JNK

Kích thước dữ liệu tôi có nghĩa là cột "dữ liệu" của DBCC sp_spaceuse
Daniel Bjork

Đó sẽ là cột "dữ liệu" của EXEC sp_spaceused.
RLF

1
Có phải mọi người đã bỏ lỡ rằng OP đang sử dụng nén trang = được kích hoạt trong tập lệnh xây dựng lại của anh ấy và tôi đoán nó không phải là trước đây. Daniel bạn có thể xác nhận?
Shanky

1
@Shanky: Câu ALTER INDEXlệnh đó trông giống như được tạo bởi mã (vì nó bao gồm một loạt các tùy chọn trong cài đặt mặc định của chúng) vì vậy tôi nghi ngờ rằng nó được xây dựng từ các tùy chọn hiện có của chỉ mục. Nhưng bạn đã đúng: nếu nén không được kích hoạt trên chỉ mục được phân cụm trước khi điều này được chạy thì điều đó chắc chắn sẽ giải thích phần lớn việc giảm dấu chân dữ liệu. (một lần nữa: Daniel, bạn có thể xác nhận cách này hay cách khác không?)
David Spillett

Câu trả lời:


16

Khi một bảng có một chỉ mục được nhóm, chỉ mục dữ liệu bảng (nếu không, bạn có một bảng loại heap). Việc xây dựng lại chỉ mục được nhóm (thực tế là bất kỳ chỉ mục nào, nhưng không gian sẽ không được tính là "dữ liệu" cho chỉ mục không được phân cụm) sẽ dẫn đến các trang được sử dụng một phần được hợp nhất thành một dạng đầy đủ hơn.

Khi bạn chèn dữ liệu vào một chỉ mục (được nhóm hoặc theo cách khác) trong các trang lá thứ tự chỉ mục được tạo khi cần thiết và bạn sẽ chỉ có một trang một phần: trang cuối cùng. Khi bạn nhập dữ liệu ra khỏi chỉ mục, một trang cần được phân chia để dữ liệu nằm đúng vị trí: bạn kết thúc với hai trang gần đầy một nửa và hàng mới đi vào một trong số đó. Theo thời gian, điều này có thể xảy ra rất nhiều, tiêu tốn một lượng không gian thừa, mặc dù trong một chừng mực nào đó, các phần chèn trong tương lai sẽ lấp đầy một số khoảng trống. Các trang không có lá cũng sẽ thấy một hiệu ứng tương tự, nhưng các trang dữ liệu thực tế có ý nghĩa lớn hơn nhiều về kích thước.

Ngoài ra xóa có thể dẫn đến một phần trang. Nếu bạn xóa tất cả các hàng trong một trang, nó sẽ được tính là "không sử dụng" nhưng nếu nó còn một hoặc nhiều hàng dữ liệu thì nó vẫn được tính là đang sử dụng. Ngay cả khi chỉ có một hàng sử dụng 10 byte trong một trang, trang đó vẫn được tính là 8192 byte trong số lượng không gian được sử dụng. Một lần nữa chèn tương lai có thể lấp đầy một số khoảng cách.

Đối với các hàng có độ dài thay đổi, các bản cập nhật cũng có thể có tác dụng tương tự: vì một hàng trở nên nhỏ hơn, nó có thể để lại không gian trong trang của nó mà sau này không dễ sử dụng lại và nếu một hàng trong một trang gần đầy sẽ phát triển lâu hơn, nó có thể buộc chia trang .

SQL Server không dành thời gian cố gắng bình thường hóa dữ liệu bằng cách sắp xếp lại cách sử dụng các trang, cho đến khi được thông báo rõ ràng như thứ tự xây dựng lại chỉ mục của bạn, vì các bài tập thu gom rác như vậy có thể là một cơn ác mộng hiệu suất.

Tôi nghi ngờ đây là những gì bạn đang thấy, mặc dù tôi nói rằng có đủ không gian được phân bổ cho ~ 2,7 lần số lượng dữ liệu hoàn toàn cần là một trường hợp đặc biệt xấu. Điều này có thể ám chỉ rằng bạn có một cái gì đó ngẫu nhiên là một trong những khóa quan trọng trong chỉ mục (có lẽ là cột UUID) có nghĩa là các hàng mới dường như không được thêm vào theo thứ tự chỉ mục và / hoặc một số lần xóa đáng kể đã xảy ra gần đây.

Ví dụ chia trang

Chèn theo thứ tự chỉ mục với các hàng có độ dài cố định trong đó bốn hàng vừa với một trang:

Start with one empty page: 
        [__|__|__|__]
Add the first item in index order:
        [00|__|__|__]
Add the next three
        [00|02|04|06]
Adding the next will result in a new page:
        [00|02|04|06] [08|__|__|__]
And so on...
        [00|02|04|06] [08|10|12|14] [16|18|__|__]

Bây giờ để thêm các hàng ngoài thứ tự chỉ mục (đây là lý do tại sao tôi chỉ sử dụng các số chẵn ở trên): Thêm 11sẽ có nghĩa là mở rộng trang thứ hai đó (không thể vì chúng có kích thước cố định), di chuyển mọi thứ trên 11 lên một (quá đắt một chỉ mục lớn) hoặc chia trang như vậy:

[00|02|04|06] [08|10|11|__] [12|14|__|__] [16|18|__|__]

Từ đây, việc thêm 1317sẽ không dẫn đến sự phân tách vì hiện tại có chỗ trong các trang có liên quan:

[00|02|04|06] [08|10|11|__] [12|13|14|__] [16|17|18|__]

nhưng thêm 03 sẽ:

[00|02|03|__] [04|06|__|__] [08|10|11|__] [12|13|14|__] [16|17|18|__]

Như bạn có thể thấy, sau những thao tác chèn đó, chúng tôi hiện có 5 trang dữ liệu được phân bổ có thể phù hợp với tổng số 20 hàng, nhưng chúng tôi chỉ có 14 hàng ở đó ("lãng phí" 30% dung lượng).

Việc xây dựng lại với các tùy chọn mặc định (xem bên dưới về "hệ số lấp đầy") sẽ dẫn đến:

[00|02|03|04] [06|08|10|11] [12|13|14|16] [17|18|__|__]

lưu một trang trong ví dụ đơn giản này. Thật dễ dàng để xem làm thế nào xóa có thể có tác động tương tự như chèn ngoài chỉ mục.

Giảm nhẹ

Nếu bạn đang mong đợi dữ liệu đến theo thứ tự khá ngẫu nhiên liên quan đến thứ tự chỉ mục, bạn có thể sử dụng FILLFACTORtùy chọn khi tạo hoặc xây dựng lại một chỉ mục để báo cho SQL Server thoát khỏi các khoảng trống để sau đó điền vào - giảm phân tách trang trong thời gian dài nhưng chiếm nhiều không gian ban đầu. Tất nhiên nhận sai giá trị này có thể làm cho mọi thứ tồi tệ hơn thay vì làm cho tình hình tốt hơn, vì vậy hãy xử lý cẩn thận.

Việc chia trang, đặc biệt là trên chỉ mục được nhóm, có thể có hàm ý hiệu suất cho việc chèn / cập nhật, do đó FILLFACTORđôi khi được điều chỉnh vì lý do đó thay vì vấn đề sử dụng không gian trong cơ sở dữ liệu có nhiều hoạt động ghi (nhưng đối với hầu hết các ứng dụng, trong đó đọc vượt quá ghi theo một số đơn đặt hàng lớn, bạn thường tốt hơn hết là để lại hệ số lấp đầy ở mức 100% trừ các trường hợp cụ thể như nơi bạn có các chỉ mục trên các cột có nội dung ngẫu nhiên hiệu quả).

Tôi giả sử các DB tên lớn khác có một tùy chọn tương tự, nếu bạn cũng cần mức độ kiểm soát này.

Cập nhật

Về ALTER INDEXcâu lệnh được thêm vào câu hỏi sau khi tôi bắt đầu gõ ở trên: Tôi giả sử rằng các tùy chọn giống như khi chỉ mục được xây dựng lần đầu (hoặc được xây dựng lại lần cuối) nhưng nếu không thì tùy chọn nén có thể rất quan trọng nếu được thêm vào thời gian xung quanh Cũng trong tuyên bố đó, fillfactor được đặt thành 85% chứ không phải 100%, vì vậy mỗi trang lá sẽ trống ~ 15% ngay sau khi xây dựng lại.


2
+1 Nếu hệ số lấp đầy trang nhỏ hơn 100%, ví dụ: nếu hệ số lấp đầy trang là 50%, chỉ số cụm mới được xây dựng lại ( bảng ) sẽ lớn gấp đôi nếu được xây dựng lại với hệ số lấp đầy 100%.
Max Vernon

6

Khi bạn xây dựng lại một chỉ mục, nó thực sự đặt tất cả dữ liệu lên các trang mới. Điều tôi nghi ngờ đã xảy ra là bạn đã xóa rất nhiều dữ liệu trước khi xây dựng lại, ví dụ như đã xóa một cột, cập nhật cột có chiều rộng thay đổi để có ít dữ liệu hơn, thay đổi kích thước cột có chiều rộng cố định hoặc xóa rất nhiều hàng. Một trong hai thao tác này có thể để lại nhiều khoảng trống trên các trang, sẽ không được thu hồi cho đến khi xây dựng lại. Cột "dữ liệu" sp_spaceusedkhông đo dữ liệu thực tế, nhưng số lượng trang 8K được sử dụng để lưu trữ dữ liệu. Các trang đó hiện đầy đủ hơn do được xây dựng lại, do đó, cùng một lượng dữ liệu phù hợp với số lượng trang nhỏ hơn.


5

Quy sp_spaceusedtrình được lưu trữ không kiểm tra tổng kích thước của các hàng trong cơ sở dữ liệu. Đó là báo cáo kích thước của không gian được phân bổ để giữ dữ liệu đó trong kích thước tích lũy của các phạm vi được phân bổ cho dữ liệu.

Nếu có sẵn sự tự do đáng kể, chẳng hạn như từ nhiều hàng bị xóa, thì việc xây dựng lại chỉ mục được nhóm sẽ thu gọn không gian trong các trang và phạm vi để có hiệu quả hơn (tức là nhỏ hơn) vì lý do hiệu suất.

Vì vậy, không có dữ liệu nào nên bị loại bỏ, nhưng quá trình xây dựng lại khiến không gian trống đó được nhúng vào các trang dữ liệu có sẵn một lần nữa.

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.