我在SQL Server 2016中有一个200 GB数据的表。所以我打算在该表中应用Clustered ColumnStore来进行磁盘压缩以及更好的性能。
但问题是在该表下有一列数据类型是NVARCHAR(MAX),而列存储索引不支持该数据类型。
所以我想的是将数据类型从NVARCHAR(max)更改为任何其他数据类型,该数据类型至少接受同一列中的81446个字符。
我已尝试过SQL中可用的其他一些数据类型,如VARCHAR(8000),但它的作用是删除8000个字符以后的其他数据。
我也试过文字。但是再次在Text中,由于限制,列存储不适用。
那么请你知道我必须使用哪种数据类型。或者有没有其他方法在同一个表中应用ColumnStore索引?
答案 0 :(得分:3)
您在这里有几个不同的问题:
问:SQL Server 2016可以在列存储索引中使用(MAX)数据类型吗?
表所需时,请勿使用聚簇列存储索引 varchar(max),nvarchar(max)或varbinary(max)数据类型。
我通常会停在那里 - 如果文档告诉你不要做某事,你可能不应该。
问:我可以在VARCHAR(8000)中存储超过8,000个字符吗?
没有。数字表示它所说的内容 - 它是您可以存储的最大字符数。如果您尝试存储其他数据,则无法存活。
问:我可以在没有这些(MAX)字段的情况下构建群集列存储吗?
是的,通过更改您的数据模型并打破表格。假设所涉及的表名为FactTable:
不幸的是,您可能不得不更改ETL过程,并且根据表中涉及的文本数量,您可能无法获得任何压缩。例如,假设表格大小的90%全部来自文本 - 那么你还没有在这里保存任何东西。
现在你开始明白为什么文档会告诉你这不是一个好主意。
答案 1 :(得分:0)
使用 LOB 列减小表大小的另一种解决方案是在存储和读取 LOB 内容时使用 SQL Server 的本机 COMPRESS() 和 DECOMPRESS() 函数。 这是 Microsoft docs 的链接。
当我发现存储在 varchar(max) 列中的 30MB json 文件根本没有被任何表压缩方法压缩时,我开始使用 COMPRESS() 和 DECOMPRESS()。 COMPRESS() 使它们缩小到原始尺寸的 5% 以下。 压缩 varchar(max)、nvarchar(max) 和 varbinary(max) 格式工作正常。
DECOMPRESS() 将返回一个二进制文件,因此请确保在需要时将其转换或转换为原始格式(varchar 或 nvarchar)。
关于性能损失,我不能说太多。有一些,但性能仍然非常适合我需要做的事情。
COMPRESS() 使用 Gzip 压缩标准。支持 Gzip 的 ETL 工具可以将已经压缩的内容写入 SQL Server,以便稍后使用 DECOMPRESS() 读取。至少 C#/.NET/SSIS 可以。我在 stackoverflow 上发现了一个 very usable C# code example。