Tăng độ chính xác thập phân đột ngột tăng kích thước của bảng


7

Tôi có một bảng như:

CREATE TABLE grid_rows(
    [grid_row_id] [int] NOT NULL,
    [grid_column_id] [smallint] NOT NULL,
    [decimal_val] [decimal](18, 6) NULL,
    [datetime_val] [datetime] NULL,
    [integer_val] [int] NULL,
    [string_val] [varchar](1024) NULL
)

Bảng này có một số 1,037,560 rows

exec sp_spaceused "grid_rows" gives:
rows         reserved    data
1,037,560    461,768KB  302,648KB`

Sau khi thay đổi độ chính xác từ (18, 6) thành (24,6), tức là ALTER TABLE grid_rows ALTER COLUMN decimal_val decimal(24, 6)

exec sp_spaceused "grid_rows" gives:
rows         reserved     data
1,037,560    641,352KB  560,832KB

Các không gian được phân bổ bởi decimal(18,6)9 bytesvà của (24, 6)13 bytes. Tham chiếu MSDN

The reserved space has increased by around 179,584 KB and data space by 260,000KB. Shouldn't it be increased by 1,037,560 * 4/1024 = 4052 KB


Bạn có thể làm rõ chính xác câu hỏi của bạn là gì?

Tôi có thể tái tạo vấn đề và điều thú vị là không gian được sử dụng cũng sẽ khác nếu bạn tạo bảng decimal(24, 6)ngay từ đầu: đối với một bảng chứa 1024 hàng, tôi nhận được 48KB decimal(18, 6), 56KB với decimal(24, 6)và 72KB với decimal(18, 6) then alter to decimal(24, 6). Tôi không có lời giải thích cho điều này, mặc dù.
Lâm Trần Duy

Nếu tôi phải đoán, tôi sẽ nói các trang dữ liệu hiện có 2 bản sao của trường được đề cập. Bản sao cũ, không còn được sử dụng và bản sao mới, lớn hơn được sử dụng.
Max Vernon

@MaxVernon - nhưng sau đó không nên chỉ ảnh hưởng đến kích thước của không gian dành riêng, thay vì kích thước dữ liệu thực tế?
Lâm Trần Duy

4
Một điều khác có thể làm tăng kích thước bảng là chia trang. Nếu các trang của bạn khá đầy đủ thì việc tăng kích thước của bất kỳ cột nào có thể buộc một số dữ liệu được chuyển sang một trang mới.
Aaron Bertrand

Câu trả lời:


4

Hãy nhớ rằng cột bị rơi vẫn còn hiện diện trong hàng .

Nhưng kẻ giết người thực sự có lẽ là, nếu đây là một đống (chỉ số cụm bảng / bảng), thì các cập nhật hàng tăng kích thước hàng có thể gây ra một đợt chuyển tiếp. Hãy xem xét rằng nếu bạn bắt đầu với các trang gần đầy 100% thì bất kỳ hàng nào tăng sẽ khiến hàng không còn vừa trong trang, do đó, một bản ghi chuyển tiếp phải được đặt đúng chỗ và hàng phải được đặt ở một nơi khác. Lặp lại điều này cho mỗi hàng (trường hợp cực đoan) và bạn có một kịch bản khá khó chịu.

Nếu là B-Tree thì kịch bản tương tự sẽ gây ra sự phân tách trang sẽ tốt hơn bởi vì trong quá trình phân chia, các hàng được sao chép lấy lại khoảng trống giữa các hàng trên trang, trường hợp chuyển tiếp heap không.


3

Tôi chỉ sử dụng DBCC INDDBCC PAGEđọc dữ liệu vật lý từ các trang đang lưu trữ DECIMAL(4,2)dữ liệu đã được sửa đổi thành DECIMAL(8,4)dữ liệu. Trường cũ được liệt kê bây giờ là DROPPED, với một trường khác chứa dữ liệu mới.

        CREATE TABLE TestDec
        (
            DecimalValue DECIMAL(4,2)
        );

        INSERT INTO TestDec VALUES (16.25);
        SELECT * FROM TestDec;

        EXEC sp_spaceused 'TestDec';

        DBCC IND('Test', 'TestDec', -1)

                    /* 20267501 happens to be the page in my database, yours WILL 
                       be different */
        DBCC TRACEON(3604) /* display output from DBCC PAGE */
        DBCC PAGE('Test',1,20267501,3) WITH TABLERESULTS

        ALTER TABLE TestDec ALTER COLUMN DecimalValue DECIMAL(8,4)
        DBCC PAGE('Test',1,20267501,3) WITH TABLERESULTS

nhập mô tả hình ảnh ở đây

Hàng 46 và 47 hiển thị các mục có liên quan.

Điều này chỉ ra rằng dữ liệu hiện có được sao chép vào một vị trí vật lý mới khi kích thước trường thập phân được thay đổi.


4
Có, và điều này chắc chắn có thể dẫn đến chia tách trang, v.v ... Tôi tin rằng bạn cần phải xây dựng lại để phục hồi không gian bị chiếm bởi các cột bị rơi.
Aaron Bertrand
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.