Joe*_*ish 7 sql-server columnstore sql-server-2016
BIT列在聚集列存储索引中使用时是否提供任何性能优势?例如,我对在 CCI 中定义列BIT而不是 所获得的任何性能优势感兴趣BIGINT。我正在使用 SQL Server 2016。
我对 CCI 压缩的工作原理知之甚少,但根据我所阅读的内容和一些测试,似乎数据类型(仅限于存储整数的精确数字)在列存储压缩方面确实无关紧要. 例如,如果我将 10 个完整的行组插入到带有BIGINT列而不是BIT列的表中,我看不到压缩行组之间的大小差异。以下是一项测试的源数据:
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);
Run Code Online (Sandbox Code Playgroud)
插入具有 8BIT列的 CCI平均花费了 18729 毫秒的 CPU 时间。该表有 56960 KB 的保留空间:
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);
Run Code Online (Sandbox Code Playgroud)
插入具有 8BIGINT列的 CCI平均花费了 18531 毫秒的 CPU 时间。该表有 56960 KB 的保留空间,与之前相同:
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);
Run Code Online (Sandbox Code Playgroud)
我们也可以在列存储 DMV 中看到这一点:
BIT在 CCI 中使用列有一些优点。例如,加载到增量存储中的数据将占用较少的BIT列空间,因为增量存储基本上是未压缩的堆。在查询计划中,估计数据大小的公式基于列的数据类型,而不是磁盘上表的大小。带BIT列的表的总数据大小为 250 MB,带BIGINT列的表的总数据大小为 880 MB。在某些情况下,250 MB 的估计大小可能会导致更好的计划。
BITCCI 色谱柱还有其他性能优势吗?抑或是数据并不重要,只要键入如您使用的是精确的数字,用于存储整数(BIT,TINYINT,SMALLINT,INT,或BIGINT)?
小智 2
首先,我们不是在比较类似的数据类型。
位定义为:
整数数据类型,可以采用 1、0 或 NULL 值。
而 BIGINT 是一个较大的整数,默认情况下会消耗大量空间。
这意味着默认情况下 SQL Server 对每个 BIT 列都有统计信息,而只有一组 BIGINT 统计信息。
正如您正确指出的,BIT 列已优化:
SQL Server 数据库引擎优化了位列的存储。如果表中有 8 位或更少位的列,则这些列将存储为 1 个字节。如果存在 9 到 16 位列,则列将存储为 2 个字节,依此类推。
您甚至考虑采用至少 8 - 10 个二进制值并将它们推入数字中肯定是有原因的。
毕竟,为什么很多只使用 INT 并节省一半的空间呢?自从我上次检查以来,2,147,483,648 是 10 个字符,仅 4 位,而 BIGINT 大约有 19 个字符,从技术上讲,这比 youvspoit 的 BIT 然后进入列的空间要小。
但这忽视了您的数据是什么。BIT 如何回答有关其代表什么的问题?10010 只是一个大于一万的数字,但在二进制中却实际代表着某种东西。如果在“节省”空间中,您在使用数据之前就强制进行转换,那么它仍然有效吗?
但请不要将 BIT 与 Tinyint 或 BIGINT 等数字数据类型混为一谈。它们有两个不同的目的。
| 归档时间: |
|
| 查看次数: |
853 次 |
| 最近记录: |