Chi phí hàng khi sử dụng Nén trang là gì?


10

Tôi đã tạo một bảng có 650 cột Số (19,4). Khi tôi bật Nén trang, bằng cách chạy

ALTER TABLE fct.MyTable REBUILD  WITH (DATA_COMPRESSION = PAGE);

tôi có

Msg 1975, Cấp 16,
Độ dài hàng 'Chỉ số PK_Mytable' của Trạng thái 1 vượt quá độ dài cho phép tối đa là '8060' byte.

nhưng 650 lần 9 byte chỉ là 5850 byte, khá xa so với giới hạn đã nêu là 8060 byte.

Máy chủ đang chạy Windows 2012 r2 với SQL Server 2016 SP1 CU2

Chi phí hàng khi sử dụng Nén trang là gì?

Đây là một số mã để hiển thị những gì tôi có nghĩa là:

/* test script to demo MSG 1975 */
DECLARE @sql NVARCHAR(max)='', @i INT =0
drop table if exists dbo.mytable;

SET @sql = 'Create table dbo.Mytable (MyTableID bigint not null 
  identity(1,1) primary key clustered, '

WHILE @i < 593 BEGIN
    SET @sql += ' Column' + LTRIM(@i) + ' numeric(19,4) null, '
    SET @i +=1
END

SET @sql += ' LastColumn int) '
--SET @sql += ' with (DATA_COMPRESSION = ROW) '
SET @sql += ' with (DATA_COMPRESSION = PAGE) '

SELECT @sql
EXEC sys.sp_executesql @sql

SELECT top 10000 * FROM dbo.MyTable MT

Nén hàng cũng thất bại, nhưng ở một số hàng khác nhau.


Khóa chính của bạn lớn cỡ nào? Nếu đây là một bảng thực tế và bạn muốn nén và nâng cao hiệu suất, tôi khuyên bạn nên đọc các chỉ mục của cột, chúng có thể tạo ra tác động khá lớn. Chi phí nén trang là sử dụng nhiều cpu hơn để giải nén.
Phụ nữ Stijn

@StijnWynants; 8 byte được sử dụng cho BigInts. Đây thực sự là một thực tế, nhưng không có đủ hàng đến để đảm bảo một chỉ số cột.
Henrik Staun Poulsen

Câu trả lời:


13

Nếu bạn thử tạo bảng của mình mà không có ràng buộc PK phân cụm và bạn sẽ gặp một lỗi khác:

Msg 1701, Cấp 16, Trạng thái 1, Dòng 1 Tạo hoặc thay đổi bảng 'Mytable' không thành công vì kích thước hàng tối thiểu sẽ là 8067, bao gồm 1530 byte chi phí nội bộ. Điều này vượt quá kích thước hàng của bảng tối đa cho phép là 8060 byte.

Trong thông báo lỗi này, bạn có thể thấy rằng có 1530 byte chi phí nội bộ để nén trang.

Bây giờ, bạn có thể làm toán:

  • 8 byte cho bigintMyTableID
  • 4 byte cho intLastColumn
  • 9 byte cho mỗi numeric(19,4)cột trong 593 (tổng số 5337 byte)
  • 1530 byte phí nén

Vì vậy, 8 + 4 + (593 * 9) + 1530 = 6879. Đợi một chút .... Vẫn còn dưới 8060. Chuyện gì thế?!


Thuật toán nén trang thực sự xếp chồng một số thuật toán nén lại với nhau. Bước đầu tiên là áp dụng nén ROW. Chi phí nén hàng không được bao gồm trong 1530 byte chi phí được liệt kê trong thông báo lỗi đó.

Bạn có thể đọc thêm về cách nén hàng hoạt động ở đây trên blog của tôiở đây trong BOL . Bạn sẽ lưu ý trong bài viết BOL rằng nó mô tả bộ numericlưu trữ là "Bộ lưu trữ này hoàn toàn giống với định dạng lưu trữ tối thiểu", nhưng không giải thích vardecimal. Bài đăng này bao gồm vardecimalnhiều hơn một chút - về cơ bản, nó thêm 2 byte phí trên mỗi cột để lưu trữ độ dài thực tế (tương tự như những gì varchar).

Nén hàng sẽ yêu cầu thêm 2 byte cho mỗi numericcột trong 593 , cộng với bigintintsẽ yêu cầu 1 byte trên mỗi cột .

Các yêu cầu lưu trữ được nén theo hàng sẽ là:

  • Chi phí 8 byte + 1 byte cho bigintMyTableID
  • Chi phí 4 byte + 1 byte cho intLastColumn
  • Chi phí 9 byte + 2 byte cho mỗi numeric(19,4)cột trong 593
  • 1188 byte phí nén ROW

8 + 4 + (593 * 9) = 5349 byte dữ liệu

Chi phí nén hàng 1 + 1 + (593 * 2) = 1188 byte

Tổng cộng 6537 byte cho lược đồ nén hàng


Bây giờ chúng ta có kích thước hàng cho lược đồ nén hàng, chúng ta có thể xem lại toán học của mình. Kích thước hàng được nén trang sẽ là kích thước dữ liệu + chi phí nén hàng + chi phí nén trang:

  • 8 byte cho bigintMyTableID
  • 4 byte cho intLastColumn
  • 9 byte cho mỗi numeric(19,4)cột trong 593
  • 1188 byte phí nén ROW
  • 1530 byte chi phí nén PAGE
  Dữ liệu 5349 byte 
+ Chi phí nén hàng 1188 byte 
+ Chi phí nén trang 1530 byte 

Tổng số 8067 byte


1
Tôi thích kết luận của bạn: "Trong hầu hết các trường hợp, bạn sẽ thấy rằng nén hàng có thể tiết kiệm một số không gian, nhưng không phải lúc nào cũng vậy." 2718 byte chi phí hoạt động nhiều hơn tôi mong đợi. Cảm ơn bạn rất nhiều vì đã dành thời gian để viết một câu trả lời chi tiết như vậy.
Henrik Staun Poulsen

1
@HenrikStaunPoulsen Một điều quan trọng khác cần nhớ là SQL Server cần phải thừa nhận rằng dữ liệu của bạn có thể không được nén. Vì vậy, ngay cả khi dữ liệu của bạn sẽ nén xuống dưới 8060 byte, SQL Server phải thực hiện các phép tính kích thước hàng dựa trên kích thước hàng tối đa theo lý thuyết cho dữ liệu không thể nén.
AMtwo

Sau 3 ngày, tôi vẫn ngạc nhiên về số lượng byte cần thiết để nén Hàng; 2 byte mỗi cột. Nén trang thêm gần 3 byte trên đó. Nhưng; cảm ơn sự giúp đỡ của bạn. Nó là hữu ích nhất.
Henrik Staun Poulsen
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.