我可以在包含 NVARCHAR(MAX) 字段的表上放置聚集列存储索引吗?

Par*_*rma 4 sql sql-server sql-server-2016

我在 SQL Server 2016 中有一个包含 200 GB 数据的表。所以我计划在该表中应用 Clustered ColumnStore 以进行磁盘压缩以及更好的性能。

但问题是在该表下有一个数据类型为 NVARCHAR(MAX) 的列,并且列存储索引不支持该数据类型。

所以我的想法是将数据类型从 NVARCHAR(max) 更改为任何其他至少接受同一列中 81446 个字符的数据类型。

我尝试了 SQL 中可用的其他一些数据类型,如 VARCHAR(8000) 但它所做的是删除了 8000 个字符之后的其他数据。

我也试过文字。但同样在 Text 中,由于限制,列存储不适用。

所以你能告诉我我必须使用什么数据类型吗?或者有没有其他方法可以在同一个表中应用 ColumnStore 索引?

Bre*_*zar 7

您在这里有几个不同的问题:

问:SQL Server 2016 可以在列存储索引中使用 (MAX) 数据类型吗?

。文档指出

当表需要 varchar(max)、nvarchar(max) 或 varbinary(max) 数据类型时,不要使用聚集列存储索引。

我通常只会停在那里 - 如果文档告诉你不要做某事,你可能不应该做。

问:我可以在 VARCHAR(8000) 中存储超过 8,000 个字符吗?

不。数字的意思是它所说的 - 它是您可以存储的最大字符数。如果您尝试存储其他数据,它将无法生存。

问:我可以在没有这些 (MAX) 字段的情况下构建聚集列存储吗?

是的,通过更改您的数据模型并分解表格。假设所涉及的表称为 FactTable:

  1. 创建一个包含大文本字段的新表 - 我们将其命名为 FactTable_Text。
  2. 使用其余字段创建一个新表 - 我们将其称为 FactTable_Data。在它上面放置一个聚集列存储索引,你会得到它的压缩。
  3. 将旧 FactTable 中的数据迁移到这些新表中
  4. 放下旧桌子
  5. 创建一个名为 FactTable 的视图,将 FactTable_Data 和 FactTable_Text 连接在一起
  6. 用户继续查询 FactTable 却不知道任何事情发生了变化

不幸的是,您可能不得不更改 ETL 过程,并且根据表格中涉及的文本数量,您可能无法获得任何压缩。例如,假设表格大小的 90% 都是由文本造成的 - 那么您实际上并没有在这里保存任何内容。

现在您开始明白为什么文档会建议您这不是一个好主意。

  • 尽管 OP 提到了 SQL Server 2016,但我想向其他访问者指出(这是 Google 上的热门搜索),SQL Server 2017+ 支持 nvarchar(max) (5认同)