技术开发 频道

SQL Server 2014 可更新聚集列存储索引

  【IT168 技术】微软在SQL Server 2012中引入了非聚集列存储索引,列存储索引能够将数据库的性能大幅提升并通过列存储压缩技术将空间使用大幅降低。但同时引入很多限制,比如无法建成聚集的列存储索引,这意味着列索引仅仅是在原有的行存储索引之上引用了底层数据而已,反而会消耗更多的存储空间。在SQL Server 2012中一旦将非聚集列存储索引建立在某个表上时,该表将变为只读,即使在数据仓库中使用列索引,每次更新或添加数据也会是一件非常琐碎的事。SQL Server 2014中的可更新聚集列索引则解决了该问题。

  一、什么是可更新聚集列存储索引

  聚集列存储索引的概念可以类比于传统的行存储,聚集索引是数据本身,列存储的概念也是一样。相比行存储索引,使用列存储索引有如下好处:

  ·首先对于聚合、扫描、分组等大查询类操作仅仅需要读取选择的列,对于需要Join多个表的星型结构等场景的查询性能提升尤其明显;

  ·其次是列索引可以更新,并且每个表中只需要一个聚集列索引即可,简化了维护操作;

  ·列索引由于是按列存储,同一列中数据类型是一样的,因此可以更容易的实现更高压缩比;

  ·列存储的表由于非常高的压缩比率,占用更少的存储空间,对于OLAP类对IO高消耗的查询来说,进一步提升了查询性能。

  二、列存储索引适用场景

  SQL Server传统的行存储方式适合于短平快的OLTP操作,因为每个聚集索引键可以用于标识行。该行存储在物理磁盘上也是连续的,因此可以利用Seek操作以非常低的成本完成选择性高的查询;而列存储索引同一行的每一列并不在物理上连续,并且列存储聚集索引中并没有“主键”的概念,因此并不存在Seek操作。因此并不适用于OLTP类操作。

  列存储更适用于OLAP操作,在OLAP操作中,并发小、查询性能瓶颈在IO而不是CPU,列存储索引可以有效提升该类查询性能。因此,列存储索引只支持Scan操作,如图1所示。

什么是可更新聚集列存储索引
▲图1.列存储索引只支持Scan操作

  三、列索引的存储方式

  列存储索引望文生义,即按列存储。该过程可以分为3个阶段,第一阶段是对一定数据的行进行分组,这就是所谓的“行组”。每个行组能够容纳102,400到1,048,576行,分组完成后,再按列切分成为列片段。最后将列片段压缩后,插入实际的列存储。如图2所示。

列索引的存储方式
▲图2.列存储的过程

  我们注意到其中有一部分行不够分组的最低条件(102,400行),那么就直接让这部分数据以传统行存储的形式进行存储,这就是所谓的DeltaStore,等数据增长到可以分组时再进行分组。

  上述列存储的两部分数据分布可以通过SQL Server 2014新引入的DMV进行观测,如图3所示。在图3中,对目前已经存在31,465行的聚集列索引插入了1000行新的数据,则SQL Server认为这部分数据不满100,000行,因此以DeltaStore的方式存在。

列索引的存储方式
▲图3.压缩后的列和Deltastore

  当再插入1000行数据时,可以观察到DeltaStore中的数据又增加了1000行,达到2000行时,依然存在DeltaStore中。如图4所示。

列索引的存储方式
▲图4.再次插入的数据依然在DeltaStore中

  当插入大量的行进行观测时会发现,虽然数据已经达到列片段的最低阈值102,400行,但该部分数据依然以DeltaStore的方式存储,如图5。

列索引的存储方式
▲图5.插入大量数据后也无法将数据压缩

  那么究竟何时会压缩这些数据并以列存储的形式存放呢,根据BOL的说法(http://msdn.microsoft.com/en-us/library/dn223749(v=sql.120).aspx),会有一个后台的线程定期检测,当发现为“关闭”状态的行组时,对其进行压缩并以列存储的形式存放,此外当重建或整理索引时也会进行压缩转存,如图6所示。

列索引的存储方式
▲图6.重建索引后归档列存储索引

6
相关文章