Các cột BIT có cung cấp bất kỳ lợi thế về hiệu suất nào cho CCI không?


7

Các BITcột có cung cấp bất kỳ lợi thế về hiệu suất khi được sử dụng trong Chỉ mục của Clustered Clusterstore không? Tôi quan tâm đến bất kỳ lợi ích hiệu suất nào đạt được từ việc xác định một cột trong CCI BITthay vì BIGINT, chẳng hạn. Tôi đang làm việc với SQL Server 2016.

Tôi có hiểu biết rất hạn chế về cách hoạt động của nén CCI, nhưng dựa trên những gì tôi đã đọc và một số thử nghiệm, có vẻ như kiểu dữ liệu (giới hạn ở các số chính xác lưu trữ toàn bộ số) thực sự không quan trọng khi nói đến nén cột . Ví dụ: nếu tôi chèn 10 nhóm hàng đầy đủ vào các bảng có BIGINTcác cột trái ngược với BITcác cột, tôi sẽ không thấy sự khác biệt về kích thước giữa các nhóm hàng được nén. Đây là dữ liệu nguồn cho một bài kiểm tra:

DROP TABLE IF EXISTS dbo.CCI_BIT_TEST_SOURCE;

CREATE TABLE dbo.CCI_BIT_TEST_SOURCE (
    ID1 BIGINT NOT NULL,
    ID2 BIGINT NOT NULL,
    ID_BIT BIT NOT NULL,
    ID_BIGINT BIGINT NOT NULL,
    INDEX CCI__CCI_BIT_TEST_SOURCE CLUSTERED COLUMNSTORE
);

INSERT INTO dbo.CCI_BIT_TEST_SOURCE WITH (TABLOCK)
SELECT
  t.RN
, t.RN
, t.RN % 2
, t.RN % 2
FROM
(
    SELECT TOP (10485760) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) RN
    FROM master..spt_values t1
    CROSS JOIN master..spt_values t2
    CROSS JOIN master..spt_values t3
) t
OPTION (MAXDOP 1);

Chèn vào CCI với 8 BITcột mất trung bình 18729 ms thời gian CPU. Bảng có 56960 KB không gian dành riêng:

DROP TABLE IF EXISTS dbo.CCI_BIT;

CREATE TABLE dbo.CCI_BIT (
    ID1 BIGINT NOT NULL,
    ID2 BIGINT NOT NULL,
    ID_BOOL_1 BIT NOT NULL,
    ID_BOOL_2 BIT NOT NULL,
    ID_BOOL_3 BIT NOT NULL,
    ID_BOOL_4 BIT NOT NULL,
    ID_BOOL_5 BIT NOT NULL,
    ID_BOOL_6 BIT NOT NULL,
    ID_BOOL_7 BIT NOT NULL,
    ID_BOOL_8 BIT NOT NULL,
    INDEX CCI__CCI_BIT CLUSTERED COLUMNSTORE
);

INSERT INTO dbo.CCI_BIT WITH (TABLOCK)
SELECT
  ID1
, ID2
, ID_BIT
, ID_BIT
, ID_BIT
, ID_BIT
, ID_BIT
, ID_BIT
, ID_BIT
, ID_BIT
FROM dbo.CCI_BIT_TEST_SOURCE
OPTION (MAXDOP 1);

Chèn vào CCI với 8 BIGINTcột mất trung bình 18531 ms thời gian CPU. Bảng có 56960 KB không gian dành riêng, giống như trước:

DROP TABLE IF EXISTS dbo.CCI_NO_BIT;

CREATE TABLE dbo.CCI_NO_BIT (
    ID1 BIGINT NOT NULL,
    ID2 BIGINT NOT NULL,
    ID_BOOL_1 BIGINT NOT NULL,
    ID_BOOL_2 BIGINT NOT NULL,
    ID_BOOL_3 BIGINT NOT NULL,
    ID_BOOL_4 BIGINT NOT NULL,
    ID_BOOL_5 BIGINT NOT NULL,
    ID_BOOL_6 BIGINT NOT NULL,
    ID_BOOL_7 BIGINT NOT NULL,
    ID_BOOL_8 BIGINT NOT NULL,
    INDEX CCI__CCI_NO_BIT CLUSTERED COLUMNSTORE
);

INSERT INTO dbo.CCI_NO_BIT WITH (TABLOCK)
SELECT
  ID1
, ID2
, ID_BIGINT
, ID_BIGINT
, ID_BIGINT
, ID_BIGINT
, ID_BIGINT
, ID_BIGINT
, ID_BIGINT
, ID_BIGINT
FROM dbo.CCI_BIT_TEST_SOURCE
OPTION (MAXDOP 1);

Chúng ta cũng có thể thấy điều này trong DMV của cửa hàng cột:

cci dmv

Có một số lợi thế khi sử dụng BITcác cột trong CCI. Ví dụ, dữ liệu được tải vào các cửa hàng delta sẽ chiếm ít không gian hơn với BITcác cột vì các cửa hàng delta về cơ bản là các đống không nén. Trong các kế hoạch truy vấn, công thức cho kích thước dữ liệu ước tính dựa trên các loại dữ liệu của các cột trái ngược với kích thước của bảng trên đĩa. Bảng có BITcác cột có tổng kích thước dữ liệu là 250 MB và bảng có BIGINTcác cột có tổng kích thước dữ liệu là 880 MB. Trong một số trường hợp, kích thước ước tính 250 MB có thể dẫn đến một kế hoạch tốt hơn.

Có bất kỳ lợi ích hiệu suất nào khác của BITcác cột cho CCI không? Hay các loại dữ liệu không thực sự quan trọng miễn là bạn đang sử dụng một số chính xác mà các cửa hàng số nguyên ( BIT, TINYINT, SMALLINT, INT, hoặc BIGINT)?


Không chính xác là một câu trả lời cho câu hỏi của bạn về ưu điểm, nhưng một nhược điểm bạn có thể xem xét: Các tổng hợp như MIN / MAX / SUM không hỗ trợ BIT. Vì vậy, bạn cần sử dụng CONVERTđể thực hiện tổng hợp như vậy và chuyển đổi đó ngăn chặn việc đẩy xuống tổng hợp. Nếu bạn cố gắng để có một MINtrên ID_BOOL_1trên cả hai bảng của bạn, tôi nghĩ bạn sẽ thấy rằng BIGINTphiên bản thực sự là nhanh hơn đáng kể vì lý do này!
Geoff Patterson

1
@GeoffPatterson Đó thực sự là động lực cho câu hỏi này. Tôi không thích cú pháp giới hạn cho các cột BIT và do đó thiếu sự hỗ trợ cho việc đẩy xuống tổng hợp. Có lẽ đối với một số bảng lưu trữ, không thể bỏ qua việc tiết kiệm không gian từ các cột BIT, nhưng tôi không muốn đưa chúng vào CCI.
Joe Obbish

Câu trả lời:


2

Đầu tiên, chúng tôi không so sánh như các loại dữ liệu.

Bit được định nghĩa là:

Một kiểu dữ liệu số nguyên có thể lấy giá trị 1, 0 hoặc NULL.

BIT

Trong khi đó BIGINT là một số nguyên lớn hơn tiêu thụ một lượng không gian đáng kể theo mặc định.

Điều đó có nghĩa là mặc định SQL Server có số liệu thống kê trên từng cột BIT và chỉ có một bộ cho BIGINT.

Như bạn đã lưu ý, các cột BIT được tối ưu hóa:

Công cụ cơ sở dữ liệu SQL Server tối ưu hóa việc lưu trữ các cột bit. Nếu có 8 cột bit trở xuống trong một bảng, các cột được lưu dưới dạng 1 byte. Nếu có từ 9 đến 16 cột, các cột được lưu dưới dạng 2 byte, v.v.

int, bigint, smallint, và tinyint

phải có một lý do mà bạn thậm chí đang cân nhắc lấy ít nhất 8 - 10 giá trị nhị phân và đẩy chúng thành một số.

Rốt cuộc, tại sao rất nhiều chỉ sử dụng INT và tiết kiệm một nửa không gian? Kể từ lần kiểm tra cuối cùng, 2.147.483.648 là 10 ký tự cho chỉ 4 bit và BIGINT có khoảng 19, về mặt kỹ thuật là ít không gian hơn BIT của youvspoit sau đó thành các cột.

Nhưng điều này đang làm mất đi dữ liệu của bạn . BIT trả lời các câu hỏi về những gì nó thể hiện? 10010 chỉ là một con số lớn hơn mười nghìn và ở dạng nhị phân thực sự đại diện cho một cái gì đó. Nếu trong "Tiết kiệm" không gian bạn đang buộc chuyển đổi trước khi sử dụng dữ liệu, liệu nó có còn hiệu quả không?

Nhưng làm ơn, đừng kết hợp BIT với kiểu dữ liệu số như Tinyint hoặc BIGINT. Họ phục vụ hai mục đích khác nhau.


1

Lợi thế về hiệu suất của CCI không chỉ liên quan đến không gian: chế độ thực thi hàng loạt cũng có để tăng tốc mọi thứ (trong các toán tử được hỗ trợ).

Kích thước hàng loạt có thể thay đổi từ 64 đến 900 hàng, do đó, sẽ hợp lý khi hy vọng rằng việc sử dụng các kiểu dữ liệu nhỏ hơn sẽ dẫn đến các lô 'đầy đủ hơn', gần với con số tối đa 900.

https://bloss.msdn.microsoft.com/sql_server_team/columnstore-index-performance-batchmode-execut/

Kinh tế với các kiểu dữ liệu dù sao cũng là một thói quen tốt - tại sao phải xem xét bigint nếu tinyint (hoặc bit) sẽ thực hiện công việc?


1
Bit không hỗ trợ tổng hợp, vì vậy nó sẽ không hỗ trợ đẩy tổng hợp. Bạn có truy vấn mẫu nào cho thấy kích thước lô lớn hơn khi hoán đổi cột BIGINT bằng BIT không, hay đó chỉ là lý thuyết?
Joe Obbish
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.