MSSQL列式索引介绍
Tags: MSSQLSQL Server列存储列式索引索引
列式索引
列存储索引是一种使用列式数据格式(称为“列存储”)存储、检索和管理数据的技术。
SQL Server 2012 通过采用列式存储的索引,大大提高了数据仓库的查询效率。这种全新的索引与其它新功能相结合,在一些特定应用场景下可以将数据仓库的查询性能提高数百倍甚至数千倍,对于一些决策支持类的查询,通常也可以达到10倍左右的性能提升。这些性能的提升,都是通过大家所熟悉的T-SQL语句以及SQL Server管理界面所实现的,因此可以和包括SQL Server Reporting Services在内的所有报表解决方案完全兼容。
列式索引将每一列单独存储在一组磁盘页中,而不是像传统方式那样在每个页中存储多个行。我们通常使用“行存储”来描述每个页中包含多行数据的堆或者B树结构。采用列式存储时,列将存储在不同的页组中,这样存储将带来以下好处:
. 只有查询所涉及到的列才会从磁盘中获取出来(在典型的事实数据表中,查询所涉及到的列不会超过总列数的15%)
. 由于每个列中都会有大量重复数据,因此这种数据结构更便于进行压缩
. 数据经过高度压缩后,缓冲区的命中率将大大提高,并且访问频繁的列将缓存在内存中,而访问不频繁的列则不会长时间占用内存
SQL Server 2012 列式索引采用“纯粹”的列式存储,而非混合模式,因为不同列中的所有数据将会分开存储在不同的页中,这样一来I/O扫描的性能以及缓冲区的命中率将会大幅提升。SQL Server是大型数据库产品中第一个支持纯列式索引的产品。虽然其它厂商声称市场上大规模使用的数据库产品不可能提供纯列式存储技术,但很荣幸我们做到了这一点!
使用列式索引
为了提高查询性能,您所要做的就是针对数据仓库中的事实表创建列式索引。如果有非常大的维度表(比如超过1000万条记录),您可以为其创建列式索引。接下来,您只需要向SQL Server提交查询,然后查询的速度将会大大加快。
为何要使用列存储索引?
列存储索引可实现极高的数据压缩级别(通常是传统方法的 10 倍),从而明显降低数据仓库存储成本。 对于分析,列存储索引实现的性能比 B 树索引高出一个量级。 列存储索引是数据仓库和分析工作负载的首选数据存储格式。 从 SQL Server 2016 (13.x)开始,可以使用列存储索引对操作工作负荷执行实时分析。
列存储索引速度较快的原因:
- 列存储来自同一个域且通常相似的值,从而提高了压缩率。 最大限度地减少或消除系统中的 I/O 瓶颈,并显著降低内存占用量。
- 较高的压缩率通过使用更小的内存中空间提高查询性能。 反过来,由于 SQL Server 可以在内存中执行更多查询和数据操作,因此可以提升查询性能。
- 批处理执行可同时处理多个行,通常可将查询性能提高 2 到 4 倍。
- 查询通常仅从表中选择几列,这减少了从物理介质的总 I/O。
何时应使用列存储索引?
建议的用例:
- 使用聚集列存储索引来存储数据仓库工作负载的事实数据表和大型维度表。 这种方法最多可将查询性能和数据压缩率提高 10 倍。 有关详细信息,请参阅用于数据仓库的列存储索引。
- 使用非聚集列存储索引对 OLTP 工作负载执行实时分析。 有关详细信息,请参阅开始使用列存储进行实时运营分析。
- 有关列存储索引的更多使用方案,请参阅 根据需要选择最佳列存储索引。
如何在行存储索引与列存储索引之间做出选择?
行存储索引最适合用于查找数据、搜索特定值的查询,或者针对较小范围的值执行的查询。 对事务工作负载使用行存储索引,因为它们往往大多需要进行表查找,而不是表扫描。
对于扫描大量数据(尤其是大型表中)的分析查询,列存储索引可提高性能。 对数据仓库和分析工作负载(尤其是事实数据表)使用列存储索引,因为它们往往需要进行全表扫描,而不是表查找。
从 SQL Server 2022 (16.x) 开始,有序聚集列存储索引可提高基于有序列谓词的查询的性能。 有序列存储索引可以改进行组消除,这可以通过完全跳过行组来提高性能。 有关详细信息,请参阅使用有序聚集列存储索引优化性能。
是否可以在同一个表中组合行存储与列存储?
是的。 自 SQL Server 2016 (13.x) 起,可以对行存储表创建可更新的非聚集列存储索引。 列存储索引存储选定列的副本,所以需要为此数据留出额外空间,但选定数据可实现平均 10 倍的压缩率。 可以同时对列存储索引和行存储索引上的事务运行分析。 列存储随行存储表中的数据更改一起更新,因此这两个索引处理的是相同数据。
自 SQL Server 2016 (13.x) 起,可以对列存储索引创建一个或多个非聚集行存储索引,并对基础列存储执行高效表查找。 其他选项也可供使用。 例如,可以通过在行存储表中使用 UNIQUE 约束来强制主键约束。 由于非唯一值无法插入到行存储表中,因此 SQL Server 无法将值插入列存储。
元数据
列存储索引中的所有列在元数据中作为包含性列存储。 列存储索引中没有任何键列。
sys.index_columns (Transact-SQL)
sys.internal_partitions (Transact-SQL)
sys.column_store_segments (Transact-SQL)
sys.column_store_dictionaries (Transact-SQL)
sys.column_store_row_groups (Transact-SQL)
sys.dm_db_column_store_row_group_operational_stats (Transact-SQL)
sys.dm_db_column_store_row_group_physical_stats (Transact-SQL)
sys.dm_column_store_object_pool (Transact-SQL)
sys.dm_db_column_store_row_group_operational_stats (Transact-SQL)
sys.dm_db_index_operational_stats (Transact-SQL)
sys.dm_db_index_physical_stats (Transact-SQL)
相关任务
所有关系表(除非指定为非聚集列存储索引)使用行存储作为基础数据格式。 如果不指定 WITH CLUSTERED COLUMNSTORE INDEX
选项,则 CREATE TABLE
将创建行存储表。