SQL Server 内存中列存储索引 使用基于列的数据存储和基于列的查询处理来存储和管理数据。 列存储索引适用于主要执行大容量加载和只读查询的数据仓库工作负荷。 使用列存储索引在传统的面向行的存储上实现高达 10 倍的查询性能 提升,对未压缩的数据大小进行高达 7 倍的数据压缩 。
注释
我们将聚集列存储索引视为存储大型数据仓库事实数据表的标准,并期望它将用于大多数数据仓库方案。 由于聚集列存储索引是可更新的,因此工作负荷可以执行大量插入、更新和删除作。
内容
基础
列存储索引是一种使用列式数据格式(称为列存储)来存储、检索和管理数据的技术。 SQL Server 支持聚集列存储索引和非聚集列存储索引。 两者都使用相同的内存中列存储技术,但它们在用途和功能方面确实存在差异。
优点
列存储索引适用于对大型数据集执行分析的大多数只读查询。 通常,这些是数据仓库工作负荷的查询。 列存储索引可以显著提高使用完整表扫描的查询的性能,但不太适合在数据中查找特定值的查询。
列存储索引优势:
列通常具有类似的数据,这会导致高压缩率。
高压缩率通过使用更小的内存中占用量来提高查询性能。 反过来,查询性能可能会提高,因为 SQL Server 可以在内存中执行更多查询和数据作。
已将名为批处理模式执行的新查询执行机制添加到 SQL Server 中,以减少大量 CPU 使用率。 批处理模式执行与列存储存储格式紧密集成并对其进行优化。 批处理模式执行有时称为基于矢量的执行或矢量化执行。
查询通常只从表中选择几个列,从而减少物理媒体的总 I/O。
列存储版本
SQL Server 2012、SQL Server 2012 并行数据仓库和 SQL Server 2014 都使用列存储索引来加速常见的数据仓库查询。 SQL Server 2012 引入了两项新功能:非聚集列存储索引和基于矢量的查询执行功能,以称为“批处理”的单元处理数据。SQL Server 2014 具有 SQL Server 2012 和可更新的聚集列存储索引的功能。
关键特征
| 适用于:SQL Server 2014 到 SQL Server 2019(15.x)。 |
在 SQL Server 中,聚集列存储索引:
企业版、开发人员版和评估版中提供。
可更新。
是整个表的主存储方法。
没有主键列。 所有列都是被包含的列。
表上的唯一索引。 它不能与任何其他索引组合。
可配置为使用列存储或列存储存档压缩。
不会以物理方式按排序顺序存储列。 而是存储数据以提高压缩和性能。
| 适用于:SQL Server 2012 到 SQL Server 2019(15.x)。 |
在 SQL Server 中,非聚集列存储索引:
可以为聚集索引或堆的某些列编制索引。 例如,它可以为常用列编制索引。
需要额外的存储空间来存储索引中列的副本。
通过重建索引或添加和删除分区来更新。它不能通过使用 DML操作(如插入、更新和删除)进行更新。
可以与表上的其他索引结合使用。
可配置为使用列存储或列存储存档压缩。
不按排序顺序以物理方式存储列。 而是存储数据以提高压缩和性能。 不需要在创建列存储索引之前对数据进行预排序,但可以改进列存储压缩。
关键概念和术语
以下关键术语和概念与列存储索引相关联。
列存储索引列 存储索引 是一种使用列式数据格式(称为列存储)来存储、检索和管理数据的技术。 SQL Server 支持聚集列存储索引和非聚集列存储索引。 两者都使用相同的内存中列存储技术,但它们在用途和功能方面确实存在差异。
列存储: 列存储 是按逻辑组织为具有行和列的表的数据,以物理方式以列方式存储数据格式。
行存储是指数据按逻辑上组织为包含行和列的表格,然后以行数据格式进行物理存储。 这是存储关系表数据的传统方法。
行组和列段为了获得高性能和高压缩率,列存储索引将表切片为行组,称为行组,然后按列顺序压缩每一行组。 行组中的行数必须足够大,能够提高压缩率,并且足够小,以从内存操作中获益。
行组 A 行组 是一组同时压缩为列存储格式的行。
列段 A 列段 是行组中数据的列。
行组通常包含每行组的最大行数,即 1,048,576 行。
每个行组包含表中每个列的一个列段。
每个列段被压缩在一起并存储于物理介质上。
非聚集列存储索引: 非聚集列存储索引 是在现有聚集索引或堆表上创建的只读索引。 它包含列子集的副本,最多包含表中的所有列。 该表是只读的,而它包含非聚集列存储索引。
非聚集列存储索引提供了一种可以用于运行分析查询的列存储索引的方法,同时对原始表执行只读操作。
聚集列存储索引聚集 列存储索引 是整个表的物理存储,也是表的唯一索引。 聚集索引是可更新的。 可以对索引执行插入、删除和更新作,并且可以将数据批量加载到索引中。
为了减少列段的碎片并提高性能,列存储索引可能会暂时将某些数据存储到名为增量存储的行存储表中,以及已删除行的 B 树 ID。 增量存储作在后台处理。 若要返回正确的查询结果,聚集列存储索引将列存储和增量存储中的查询结果组合在一起。
增量存储仅用于聚集列存储索引, 增量 存储是一个行存储表,用于存储行,直到行数足够大,可移动到列存储中。 Delta 存储与聚集列存储索引结合使用,以提高加载和其他 DML 操作的性能。
在大批量加载期间,大多数行直接进入列存储,而无需通过增量存储区。 大容量加载结束时的某些行的数量可能太少,无法满足行组的最小大小,即 102,400 行。 发生这种情况时,最终行会进入增量存储,而非列存储。 对于小于 102,400 行的小批量数据加载,所有行都直接转入增量存储。
当增量存储区达到最大行数时,它将被关闭。 元组移动流程检查已闭合的行组。 当找到关闭的行组时,它会压缩该行组并将其存储到列存储中。
加载数据
将数据加载到非聚集列存储索引中
若要将数据加载到非聚集列存储索引中,请先将数据加载到存储为堆或聚集索引的传统行存储表中,然后使用 CREATE COLUMNSTORE INDEX (Transact-SQL) 创建非聚集列存储索引。
具有非聚集列存储索引的表是只读的,直到删除或禁用索引为止。 若要更新表和非聚集列存储索引,可以进出切换分区。还可以禁用索引、更新表,然后重新生成索引。
有关详细信息,请参阅 使用非聚集列存储索引
将数据加载到群集列存储索引中
如图所示,若要将数据加载到聚集列存储索引中,SQL Server:
将最大大小的行组直接插入到列存储中。 加载数据时,SQL Server 将按先到先发顺序的数据行分配给打开的行组。
对于每个行组,在达到最大大小后,SQL Server:
将行组标记为已关闭。
绕过增量存储。
使用列存储压缩的行组压缩每个列段。
以物理方式将每个压缩列段存储在列存储中。
将剩余的行插入列存储或增量存储,如下所示:
如果行数满足每行组要求的最低行数,则行将添加到列存储中。
如果行数少于行组的最小行数,这些行会被添加到 deltastore 中。
有关增量存储任务和进程的详细信息,请参阅 使用聚集列存储索引
性能提示
规划足够的内存以并行创建列存储索引
创建列存储索引默认情况下是一种并行操作,除非内存受到约束。 并行创建索引要求比按顺序创建索引更多的内存。 在内存充足的情况下,创建列存储索引相当于在同一列上生成 B 树所用时间的 1.5 倍。
创建列存储索引所需的内存取决于列数、字符串列的数目、并行度 (DOP) 和数据特性。 例如,如果表的行数少于 100 万行,SQL Server 将仅使用一个线程来创建列存储索引。
如果表的行数超过 100 万行,但 SQL Server 无法获得足够大的内存授予以使用 MAXDOP 创建索引,则 SQL Server 会根据需要自动减少 MAXDOP,以适应可用内存授予。 在某些情况下,DOP 必须减小到一个以便在受到约束的内存下生成索引。
相关任务和主题
非聚集列存储索引
有关常见任务,请参阅 使用非聚集列存储索引。
聚集列式存储索引
有关常见任务,请参阅 使用聚集列存储索引。
ALTER INDEX (Transact-SQL) 使用 REBUILD 或 REORGANIZE。
元数据
列存储索引中的所有列都作为包含的列存储在元数据中。 列存储索引没有键列。