列存储段消除(ColumnStore Segment Elimination)
列存储索引是好的!对于数据仓库和报表工作量,它们是真正的性能加速器。与聚集列存储结合,你会在常规行存储索引(聚集索引,非聚集索引)上获得巨大的压缩好处。而且创建聚集列存储索引非常简单:
CREATE CLUSTERED COLUMNSTORE INDEX ccsi ON TableName
GO
但这是你对聚集列存储需要知道的一切?并不是,如你在这篇文章会看到的……
什么是列存储段(ColumnStore Segments)?
在我各个研讨会和公共培训课程期间,我经常开玩笑:一旦你开释使用聚集列存储索引,你就不需要知道索引的更多信息。使用聚集列存储索引很太多的优点,它会带来巨大的性能提升:
- 更好的压缩
- 批处理模式执行
- 更少I/O,更好内存管理
- 段消除
如你从下例子看到的,在SQL Server里创建聚集列存储索引非常简单:
CREATE CLUSTERED COLUMNSTORE INDEX idx_ci ON FactOnlineSales
GO
你只需指定表名,没别的。甚至你不需要担心聚集键列,因为这个概念对列存储索引不适用。很简单,是不是?让我们在适当的地方用刚才的聚集索引运行一个简单的查询:
-- Segment Elimination doesn't work quite well, because
-- we have a lot of overlapping Segments.
SELECT
DateKey,
SUM(SalesAmount)
FROM FactOnlineSales_Temp
WHERE
DateKey >= ''
AND DateKey <= ''
GROUP BY
DateKey
GO
这个查询非常快,因为对于查询执行,SQL Server可以使用聚集列存储索引。从STATISTICS IO输出也向你展示了,对于聚集列存储索引不需要很多LOB Logical Reads:

但那些段读取(Segment Read)和段跳过(Segment Skipped)度量呢?
你们也许知道列存储索引内部分成所谓的列存储段(ColumnStore Segments)。一个列存储段通常指定到特定的列和行组。一个行组包含近100万行。下图很好的展示了这个重要概念:

来源:https://www.microsoft.com/en-us/research/publication/enhancements-to-sql-server-column-stores/
什么是列存储段消除(ColumnStore Segment Elimination)?
这里最重要的是,对于每个列存储段,SQL Server内部存储了最小和最大的值。基于这些值,SQL Server可以进行所谓的段消除。段消除意味着SQL Server只读取包含请求数据的那些段(在访问列存储索引时)。你可以认为它是和分区消除一样得方式,在你和分区表打交道的时候。但这里的消除发生在列存储段级别。
如你在刚才的图片所见,在列存储索引访问期间SQL Server不能消除任何段,因为默认情况下,在列存储索引里你没有排列顺序。你数据的排列顺序取决于在执行计划里,在你创建列存储索引时,SQL Server如何读取数据:

如你所见,聚集列存储索引通过从最初包含数据的堆表创建。因此在聚集列存储索引里,你没有排列顺序,因此段消除不能很好为你工作。
如何改善情况?在你的数据里首先通过创建传统的行存储聚集索引来强制排序,然后修改它为聚集列存储索引!偶滴神啊……
-- Now we create a traditional RowStore Clustered Index to sort our
-- table data by the column "DateKey".
CREATE CLUSTERED INDEX idx_ci ON FactOnlineSales_Temp(DateKey)
GO -- "Swap" the Clustered Index through a Clustered ColumnStore Index
CREATE CLUSTERED COLUMNSTORE INDEX idx_ci ON FactOnlineSales_Temp
WITH (DROP_EXISTING = ON)
GO
有了传统的聚集行存储索引就位,当你创建聚集列存储索引时,在执行计划里,查询优化器会引用这个索引:

作为副作用,在聚集列存储索引里,你现在应该有已排序的数据,段消除应该会很好处理:
-- Segment Elimination works better than previously, but still not perfectly.
SELECT
DateKey,
SUM(SalesAmount)
FROM FactOnlineSales_Temp
WHERE
DateKey >= ''
AND DateKey <= ''
GROUP BY
DateKey
GO
但当你再次查看STATISTICS IO的输出,SQL Server还是需要读取很多段,只跳过其中几个:

但为什么SQL Server不能跳过所有的段而只跳过几个?问题存在于聚集列存储的创建。当你回头看刚才的执行计划,你会看到ColumnStore Index Insert (Clustered) 运算符是并行运行的——通过多个工作者线程。而且这些工作者线程再次破坏了聚集列存储索引里你数据的排序!你从聚集行存储索引里进行你的数据读取,然后聚集列索引的并行创建重排了你的数据……伤及无辜~~~
你只能通过使用MAXDOP为1的聚集列存储创建来解决这个问题:
CREATE CLUSTERED COLUMNSTORE INDEX idx_ci ON FactOnlineSales_Temp
WITH (DROP_EXISTING = ON, MAXDOP = 1)
GO
这听起来很糟糕,事实也如此!但这是唯一让你在列存储索引里阻止重排你数据的解决方法。当你接下来从聚集列存储数据读取后,你会看到SQL Server终于能跳过所有的段:

小结
聚集列存储索引很好——真的很好!但默认段消除不能很好进行,因为在你的聚集列存储里没有预定义的排序。因此在你调优你的列存储查询时,你要确保段消除可以正常进行。而且有时候你甚至需要通过使用MAXDOP 1来阻止你的数据排序……
感谢关注!
原文链接:
https://www.sqlpassion.at/archive/2017/01/30/columnstore-segment-elimination
列存储段消除(ColumnStore Segment Elimination)的更多相关文章
- 浅谈MSSQL2012中的列存储索引(columnstore indexes)
列存储索引为MSSQL2012版本中引进的一个新特性.所有版本MSSQL中标准查询处理模式采用一次一行模型,操作符每次处理一行数据.列存储索引中增加了一种新的基于向量的查询执行功能,通过这种功能,操作 ...
- SQL Server 2012 列存储索引分析(翻译)
一.概述 列存储索引是SQL Server 2012中为提高数据查询的性能而引入的一个新特性,顾名思义,数据以列的方式存储在页中,不同于聚集索引.非聚集索引及堆表等以行为单位的方式存储.因为它并不要求 ...
- SQL Server 2016:内存列存储索引
作者 Jonathan Allen,译者 谢丽 SQL Server 2016的一项新特性是可以在“内存优化表(Memory Optimized Table)”上添加“列存储索引(Columnstor ...
- SQL Server 列存储索引 第二篇:设计
列存储索引可以是聚集的,也可以是非聚集的,用户可以在表上创建聚集的列存储索引(Clustered Columnstore Index)或非聚集的列存储索引(Nonclustered Columnsto ...
- SQL Server ->> ColumnStore Index(列存储索引)
Columnstored index是SQL Server 2012后加入的重大特性,数据不再以heap或者B Tree的形式存储(row level)存储在每一个数据库文件的页里面,而是以列为单位存 ...
- SQL Server 列存储索引概述
第一次接触ColumnStore是在2017年,数据库环境是SQL Server 2012,Microsoft开始在SQL Server 2012中推广列存储索引,到现在的SQL Server 201 ...
- SQL Server 2014聚集列存储索引
转发请注明引用和原文博客(http://www.cnblogs.com/wenBlog) 简介 之前已经写过两篇介绍列存储索引的文章,但是只有非聚集列存储索引,今天再来简单介绍一下聚集的列存储索引,也 ...
- SQL Server 列存储索引强化
SQL Server 列存储索引强化 SQL Server 列存储索引强化 1. 概述 2.背景 2.1 索引存储 2.2 缓存和I/O 2.3 Batch处理方式 3 聚集索引 3.1 提高索引创建 ...
- 在SQL Server 2014里可更新的列存储索引 (Updateable Column Store Indexes)
传统的关系数据库服务引擎往往并不是对超大量数据进行分析计算的最佳平台,为此,SQL Server中开发了分析服务引擎去对大笔数据进行分析计算.当然,对于数据的存放平台SQL Server数据库引擎而言 ...
随机推荐
- SpringMVC轻松学习-注解的使用(三)
根据上一讲的例子,我们下面就注解的使用进行详细说明. 我们采用sprng MVC开发项目时,通常都会采用注解的方式,这样可以大大提高我们的开发效率.实现零配置.下面我们从零开始重新做一个spring ...
- SQLite Lemon 语法分析器学习与使用
本文是浙江大学出版社的<LEMON语法分析生成器(LALR 1类型)源代码情景分析>学习笔记. 用到的Windows下的编译器介绍MinGW(http://www.mingw.org/): ...
- Codeforces #350
A题: 题意:判断火星上的节假日最多和最少 分析:除以7,然后我们对原数模7的余数进行判断一下即可 #include <iostream> #include <cstdio> ...
- 如何成为一名优秀的UI设计师
zccst整理 因为我自己就是一个 0 美术基础.非计算机.非艺术类科班出身,但从事视觉设计工作的同学,所以很多和题主一样大学里学着不喜欢的专业,想要转设计但又不知从何开始的朋友都来问过我类似的问题, ...
- UVA 11551 Experienced Endeavour
矩阵快速幂. 题意事实上已经告诉我们这是一个矩阵乘法的运算过程. 构造矩阵:把xi列的bij都标为1. 例如样例二: #include<cstdio> #include<cstrin ...
- mysql数据库中间件研究
随着互联网的发展,数据量的不断增大. 单台实例已经远远无法满足业务的需要. 对数据库分库分表的需求不断的增加随之而来的就是数据库中间件的开发. 一. 单台实例主要面临下面几个问题: 1. 数据量太大 ...
- ios UIKit动力 分类: ios技术 2015-07-14 12:55 196人阅读 评论(0) 收藏
UIkit动力学是UIkit框架中模拟真实世界的一些特性. UIDynamicAnimator 主要有UIDynamicAnimator类,通过这个类中的不同行为来实现一些动态特性. 它一般有两种初始 ...
- iOS纯代码手动适配 分类: ios技术 2015-05-04 17:14 239人阅读 评论(0) 收藏
首先说下让自己的程序支持iPhone6和6+,第一种使用官方提供的launch screen.xib,这个直接看官方文档即可,这里不再多述:第二种方法是和之前iPhone5的类似,比较简单,为iPho ...
- Listener
通过Listner获得当前的用户个数 package listener; import javax.servlet.ServletContext; import javax.servlet.Servl ...
- [转载] centos6.x x64 安装python2.7
本文转载自: http://www.centoscn.com/image-text/install/2016/0323/6906.html CentOS的设计理念中有一点是:持久可用.要达到这个目的, ...