Tại sao không gian dữ liệu của bảng có thể chiếm gấp 4 lần kích thước của dữ liệu thô?


18

Tôi có một bảng với các hàng 490 M và 55 GB không gian bảng, vì vậy khoảng 167 byte mỗi hàng. Bảng có ba cột: a VARCHAR(100), a DATETIME2(0)và a SMALLINT. Độ dài trung bình của văn bản trong VARCHARtrường là khoảng 21,5, vì vậy dữ liệu thô phải ở khoảng 32 byte mỗi hàng: 22 + 2 cho VARCHAR, 6 cho DATETIME2và 2 cho số nguyên 16 bit.

Lưu ý rằng không gian trên chỉ là dữ liệu, không phải chỉ mục. Tôi đang sử dụng giá trị được báo cáo trong Thuộc tính | Lưu trữ | Chung | Không gian dữ liệu.

Tất nhiên phải có một số chi phí, nhưng 135 byte mỗi hàng có vẻ như rất nhiều, đặc biệt là đối với một bảng lớn. Tại sao điều này có thể được? Có ai khác nhìn thấy số nhân tương tự? Những yếu tố có thể ảnh hưởng đến lượng không gian thêm cần thiết?

Để so sánh, tôi đã thử tạo một bảng có hai INTtrường và 1 M hàng. Không gian dữ liệu cần có là 16,4 MB: 17 byte mỗi hàng, so với 8 byte dữ liệu thô. Một bảng thử nghiệm khác có một INTvà một VARCHAR(100)quần thể có cùng văn bản với bảng thực sử dụng 39 byte mỗi hàng (44 hàng K), trong đó tôi sẽ mong đợi 28 cộng một chút.

Vì vậy, bảng sản xuất có nhiều chi phí đáng kể. Đây có phải là vì nó lớn hơn? Tôi hy vọng kích thước chỉ mục sẽ xấp xỉ N * log (N), nhưng tôi không hiểu tại sao không gian cần thiết cho dữ liệu thực tế là phi tuyến tính.

Cảm ơn trước cho bất kỳ con trỏ!

CHỈNH SỬA:

Tất cả các lĩnh vực được liệt kê là NOT NULL. Bảng thực có một cụm PK trên VARCHARtrường và DATETIME2trường, theo thứ tự đó. Đối với hai bài kiểm tra, đầu tiên INTlà PK (cụm).

Nếu nó quan trọng: bảng là một bản ghi kết quả ping. Các trường là URL, ngày / giờ ping và độ trễ tính bằng mili giây. Dữ liệu liên tục được thêm vào và không bao giờ được cập nhật, nhưng dữ liệu sẽ bị xóa theo định kỳ để cắt giảm xuống chỉ còn một vài bản ghi mỗi giờ trên mỗi URL.

CHỈNH SỬA:

Một câu trả lời rất thú vị ở đây cho thấy rằng, đối với một chỉ mục có nhiều đọc và viết, việc xây dựng lại có thể không có lợi. Trong trường hợp của tôi, không gian tiêu thụ là một mối quan tâm, nhưng nếu hiệu suất ghi là quan trọng hơn, người ta có thể tốt hơn với các chỉ số yếu.

Câu trả lời:


11

Sau khi thảo luận trong các ý kiến ​​về câu hỏi ban đầu, trong trường hợp này, không gian bị mất là do sự lựa chọn của cụm cụm, dẫn đến sự phân mảnh lớn.

Luôn luôn đáng kiểm tra trạng thái phân mảnh thông qua sys.dm_db_index_physical_stats trong những tình huống này.

Chỉnh sửa: Theo dõi cập nhật trong ý kiến

Mật độ trang trung bình (trước khi xây dựng lại chỉ mục được nhóm) là 24%, hoàn toàn phù hợp với câu hỏi ban đầu. Các trang chỉ đầy 1/4, vì vậy tổng kích thước gấp 4 lần kích thước dữ liệu thô.


7

Các cấu trúc trên đĩa có phí:

  • tiêu đề hàng
  • null bitmap + con trỏ
  • độ dài cột thay đổi
  • con trỏ phiên bản hàng (tùy chọn)
  • ...

Lấy 2 x 4 byte int cột, bạn có

  • Tiêu đề hàng 4 byte
  • Con trỏ 2 byte đến bitmap NULL
  • 8 byte cho 2 cột int
  • Ảnh bitmap 3 byte NULL

Wow 17 byte!

Bạn có thể tương tự cho bảng thử nghiệm thứ hai của bạn có nhiều chi phí như bảng gốc của bạn:

  • 2 byte cho số lượng cột có chiều dài thay đổi
  • 2 byte cho mỗi cột có chiều dài thay đổi

Tại sao lại có sự khác biệt? Ngoài ra (tôi sẽ không liên kết đến những cái này)

  • Bạn đã bao giờ xây dựng lại các chỉ mục để chống phân mảnh chúng?
  • xóa không lấy lại không gian
  • các trang dữ liệu sẽ phân tách nếu bạn chèn vào giữa
  • cập nhật có thể gây ra con trỏ về phía trước (để lại một khoảng cách)
  • tràn hàng
  • loại bỏ cột varchar mà không xây dựng lại chỉ mục hoặc DBCC R CLE RÀNG
  • heap hoặc bảng (heap không có chỉ mục cụm = các bản ghi rải rác khắp nơi)
  • Mức cô lập RCSI (thêm 14 byte mỗi hàng)
  • khoảng trắng theo dõi (SET ANSI_PADDING được BẬT theo mặc định) trong varchar. Sử dụng DATALENGTH để checl, không LEN
  • Chạy sp_spaceuse với @updateusage = 'true'
  • ...

Xem điều này: SQL Server: Làm cách nào để tạo một bảng lấp đầy một trang 8 KB?

Từ SO:


Mẫu cột int 2x4 byte không chính xác 100%. Bạn sẽ có tiêu đề hàng 4 byte (2 byte trạng thái và 2 byte cho kích thước dữ liệu có độ dài cố định). Sau đó, bạn sẽ có 2x4 byte cho dữ liệu. Hai byte cho số cột và một byte cho bitmap null, cho tổng chiều dài bản ghi là 15 byte, không phải 17.
Đánh dấu S. Rasmussen

@Mark S. Rasmussen: Nơi nào bạn nhận được "2 byte cho kích thước dữ liệu có độ dài cố định"? MSDN? Và bitmap null luôn là 3 byte: sqlskills.com/bloss/paul/post/, + + msdn.microsoft.com/en-us/l
gbn

Wow, chi tiết tuyệt vời! Tôi đã tính đến trường độ dài của VARCHARs trong ước tính của tôi ở trên, nhưng không tính số lượng cột. Bảng này không có các trường NULLable (nên đã đề cập đến điều đó), liệu nó có còn phân bổ byte cho chúng không?
Jon của tất cả các giao dịch

Các chỉ số xây dựng lại sẽ ảnh hưởng đến phần dữ liệu của không gian cần thiết? Có lẽ xây dựng lại các chỉ số cụm sẽ. Việc chèn sẽ xảy ra ở giữa, rất nhiều, mặc dù nếu tôi hoán đổi thứ tự của các trường phân cụm sẽ dừng lại. Hầu hết phần còn lại không nên áp dụng trong trường hợp này, nhưng đó là tài liệu tham khảo tuyệt vời cho trường hợp chung. Tôi sẽ kiểm tra các liên kết của bạn. Đồ tốt!
Jon của tất cả các giao dịch

1
@gbn 2 byte cho kích thước dữ liệu có độ dài cố định là một phần của tiêu đề hàng 4 byte mà bạn đề cập. Đây là con trỏ trỏ đến cuối phần chiều dài dữ liệu cố định / bắt đầu đếm số cột / bitmap null. Bitmap NULL không phải lúc nào cũng là ba byte. Nếu bạn bao gồm số lượng cột, thì nó sẽ có tối thiểu ba byte, nhưng có thể nhiều hơn - tôi chia bitmap và số cột trong mô tả của tôi. Ngoài ra, bitmap NULL không phải lúc nào cũng có mặt, mặc dù nó sẽ nằm trong trường hợp này.
Đánh dấu S. Rasmussen

5

Các loại dữ liệu đã thay đổi theo thời gian? Các cột có chiều dài thay đổi đã được gỡ bỏ? Các chỉ số đã được phân mảnh thường xuyên nhưng không bao giờ được xây dựng lại? Có rất nhiều hàng đã bị xóa hoặc có rất nhiều cột có độ dài thay đổi được cập nhật đáng kể? Một số thảo luận tốt ở đây .


Tôi tin tưởng 97% rằng tôi đã không thay đổi loại dữ liệu hoặc xóa một trường. Nếu tôi đã làm, nó sẽ thực sự sớm khi bảng có ít hàng hơn nhiều. Không có xóa hoặc cập nhật, dữ liệu chỉ được thêm vào.
Jon của tất cả các giao dịch

Correction: có được xóa, và khá một chút. Bảng có sự tăng trưởng ròng đáng kể, vì vậy tôi tưởng tượng rằng không gian này sẽ nhanh chóng được sử dụng lại.
Jon của tất cả các giao dịch

Với nhiều lần xóa, dữ liệu có thể được sử dụng lại hoặc không. Phím phân cụm của bảng là gì? Được chèn vào giữa bàn hoặc ở cuối?
mrdenny

Khóa cụm là hợp chất, trên VARCHARDATETIME2các trường, theo thứ tự đó. Chèn sẽ được phân phối đều cho trường đầu tiên. Đối với trường thứ hai, các giá trị mới và sẽ luôn lớn hơn bất kỳ giá trị nào hiện có.
Jon của tất cả các giao dịch
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.