SQL Server Column Store Indeses

SQL Server Column Store Indeses

1. 概述

2. 索引存储

2.1 列式索引存储

2.2 数据编码和压缩

2.2.1 编码

2.2.2 优化行顺序

2.2.3 压缩

2.3 I/O和Cache

3 查询处理和优化

3.1 查询处理加强

3.2 查询优化

1. 概述

SQL Server 11增加了新特性列存储索引和相关的查询操作符。批量行处理来提高数据仓库的查询性能。

传统的数据库系统使用行存储的,heap,btree都是。这种数据组织方式对于,只处理到一部分数据的事务处理表现很好,但是并不适应数据仓库的,数据仓库通常是对扫描很多记录,但是只涉及到某一些行。这个时候列方式组织就能执行的很好。因为可以读取需要的列,并且列存储的数据可以得到很好的压缩。

SQL Server列存储索引是纯粹的列存储,不是混合的。不同的列被存放在不同的page下。

使用1TB测试数据库(TPC-DS),catalog_sales包含1.44billion条数据,使用星型结构来测试列存储索引的性能提升,只对事实表做列存储索引,其他表都是行存储。在40核启用了超线程,256GB内存,磁盘性能在10GB/sec设备上测试。

SELECT  w_city ,w_state ,d_year ,SUM(cs_sales_price) AS cs_sales_price

FROM    Warehouse ,catalog_sales ,date_dim

WHERE   w_warehouse_sk = cs_warehouse_skAND cs_sold_date_sk = d_date_skAND w_state = 'SD'AND d_year = 2002

GROUP BY w_city , w_state ,d_year

ORDER BY d_year , w_state , w_city;

比较容易看出性能,在improvement行中可以看出,CPU花费少了13倍,在cold情况下执行时间少了25倍。

2. 索引存储

在SQL Server 11之前所有的索引都是以行存储的。不管是btree还是heap。

列存储,以新的索引类型引入到SQL Server列存储索引。设计的目的是为了加快列的扫描。

2.1 列式索引存储

列存储保存方式如下:

  1.       把行转化为column segment,先把行分为一个个的row groups,每个groups由1million数据。每个row group独立的进行编码和压缩。生产一个压缩的column segment,里面只包含一个列。

如图表分为3个row group,独立的进行编码和压缩,生成9个压缩的column segments。

  2.       然后使用现有的blob存储机制来保存这些压缩的column segments。Segment目录用来跟踪每个segment的位置,这样每个segment可以很容易的被定位。这个segment目录被保存在系统表可以使用sys.column_store_segments来查看,视图里面也保存了一些元数据。

2.2 数据编码和压缩

数据存储是使用压缩的方式来减少存储空间和I/O消耗。可以选择允许column segment直接使用不需要解压缩。压缩步骤如下:

1.对所有的column的值进行编码。

2.优化行的顺序。

3.对每个行进行压缩。

2.2.1 编码

编码就是把列值转化为唯一的类型:32bit或者64bit。支持2个类型的encode:基于字典的编码和基于值的编码。

基于字典的编码把不同的值转为连续的int值的集合。存入数据目录,本质上是存入以dataids为索引的一个数组中。每个数据字典保存在独立的blob中,可以使用sys.column_store_dictionaries查看。

基于值的编码应用在int或者decimal数据类型上。把某个范围的值弄小。基于值的编码由2部分组成:基值和指数。

一旦指数被选中,column segment上的值就会被调整。

2.2.2 优化行顺序

重要的性能提升主要是来自于压缩,数据使用RLE压缩(run-length encoding)。RLE在许多一样的数据在一起的时候压缩表现会很好。因为在row groups中顺序是不重要的,所以可以随意的重新组织顺序来提高压缩效率。

我们使用vertipaq算法来重新重新组织row group中的顺序,提高RLE的压缩性能。

2.2.3 压缩

一旦row group中的行被重新排序,就可以使用RLE来压缩。

2.3 I/O和Cache

Blob存储的column segment或者字典可能跨多个page,当我们读入内存的时候column segment和字典被保存在新的cache中用来保存大对象,而不是基于page 的buffer pool中。而且每个对象都是连续的,没有空隙。

为了提高I/O性能,预读可以被应用在segment内和多个segment上。对于磁盘存储,可以使用额外的压缩,是否使用额外的压缩,需要在I/O和cpu之间平衡。

3 查询处理和优化

3.1 查询处理加强

标准的查询处理是基于行的,一次处理一行,为了减少cpu,使用了新的处理方式,以批处理的方式一次性处理一批行。批处理方式适用于OLAP但是不会取代行处理在OLTP中的地位。

SQL Server没有去创建一个新的引擎,而是在原来的引擎上面做扩展。有以下好处:

1.用户不需要花时间在新的引擎上,和不需要再2个引擎上做转化。

2.极大的减少了实现引擎的花费

3.查询计划可以混合两个操作。

4.查询可以自动的在batch和row操作间转化。

5.所有的特性相容。

新的batch有独立的访问方法有不同的数据源支持,列存储索引的访问方法支持谓词和bitmap过滤。Batch模式一般适用于数据密集的计算,计算复制的过滤条件,select列表,join和聚合。

新的访问方法有新的优化,如:延迟字符串实例化和透明使用新的迭代器。虽然批处理方式可以减少cpu处理时间,但是达不到目标。

有一些额外的优化方式:

1.新的迭代器针对最新的cpu进行优化,增加内存的吞吐量。

2.bitmap过滤的实现。

3.runtime资源管理被提升,可以让操作以更灵活的方式共享。

3.2 查询优化

和其他索引不同,列存储索引不能很好的支持point query和range scan,因为列存储索引没有顺序,没有统计信息。列存储索引值提供高压缩的数据来减少cpu和io,对于scan可以从列存储索引上提升性能。

是否使用batch处理方式由查询分析器决定,也可以混合row和batch处理,但是2者之间的转化是有花费的,因此mssql会限制转化次数。

为了在生成的图形计划中区分batch和row,加入了一个新的属性,用这个属性来区分是batch还是row。,也可以决定是否有必要做转化。所有的batch操作要求输入都是batch,row操作输入都是row。

除了batch处理方法,也引入的新的方法来控制多个join。Sql server优化器视图把inner join转化为一个多维join操作。好处是可以一次性处理整个join graph。

1.我们先通过join的表达式和谓词来识别那个join key 是唯一的。使用识别的唯一信息来判断哪些是事实表,哪些是维度表,事实表不会有唯一信息。

2.然后从最小的事实表开始展开join graph,尽量多的覆盖维度表,在事实表周围形成一个雪花型。然后处理另外一个试试表。

3.之后,我们会有多个雪花型join,然后从最大的事实表开始,递归的把周围的雪花以维度表方式加入,开始形成最终的执行计划。首先,识别哪些join值得创建bitmap过滤,一旦识别就创建一个right deep join树,把维度表放在左边,事实表放在右边。每个维度表可能都是一个雪花型,然后以递归的方式分解每一个雪花。在每个join上,确定条件,检查是否可以使用batch,如果不行则用row模式。若到达了,所有吧可以batch的放在下面,其他的放在上面。

参考:

SQL Server Column Store Indexes

SQL Server Column Store Indeses的更多相关文章

  1. SQL Server 2016新特性:Query Store

    使用Query Store监控性能 SQL Server Query Store特性可以让你看到查询计划选择和性能.简化了性能调优,可以快速的发现因为查询计划的选择导致的性能的差别.Query Sto ...

  2. SQL Server 列存储索引强化

    SQL Server 列存储索引强化 SQL Server 列存储索引强化 1. 概述 2.背景 2.1 索引存储 2.2 缓存和I/O 2.3 Batch处理方式 3 聚集索引 3.1 提高索引创建 ...

  3. P6 Professional Installation and Configuration Guide (Microsoft SQL Server Database) 16 R1

    P6 Professional Installation and Configuration Guide (Microsoft SQL Server Database) 16 R1       May ...

  4. 在SQL Server 2014里可更新的列存储索引 (Updateable Column Store Indexes)

    传统的关系数据库服务引擎往往并不是对超大量数据进行分析计算的最佳平台,为此,SQL Server中开发了分析服务引擎去对大笔数据进行分析计算.当然,对于数据的存放平台SQL Server数据库引擎而言 ...

  5. Reset Identity Column Value in SQL Server (Identity Reset)

    前言:今天在群里看到有人在问SQL Server自增值重置问题(sqlserver identiy column value reset ) 闲话少说,直接上代码: 正文: --create tabl ...

  6. Part 4 Identity Column in SQL Server

    Identity Column in SQL Server If a column is marked as an identity column, then the values for this ...

  7. SQL Server中TempDB管理(version store的逻辑结构)

    原文:SQL Server中TempDB管理(version store的逻辑结构) 原文来自: http://blogs.msdn.com/b/sqlserverstorageengine/arch ...

  8. SQL Server 子查询错误:No column name was specified for column 2 of 'a' error (转载)

    问: I have a MySQL query and I ran it working fine but same query showing error in SQL Server. SQL Se ...

  9. 如何在SQL Server查询语句(Select)中检索存储过程(Store Procedure)的结果集?

    如何在SQL Server查询语句(Select)中检索存储过程(Store Procedure)的结果集?(2006-12-14 09:25:36) 与这个问题具有相同性质的其他描述还包括:如何 ...

随机推荐

  1. grape动态PHP结构(一)——目录结构与配置文件

    一.结构介绍 结构的名字grape,中文名叫葡萄,因为最近一个同事经常带葡萄到公司给我们吃,受到启发想到了这个名字. 1)本结构需要在PHP5.5中运行,如果要在5.4中运行,有些地方就要做些修改 2 ...

  2. hibernate笔记--缓存机制之 二级缓存(sessionFactory)和查询缓存

    二级缓存(sessionFactory): Hibernate的二级缓存由SessionFactory对象管理,是应用级别的缓存.它可以缓存整个应用的持久化对象,所以又称为“SessionFactor ...

  3. 数据库操作提示:Specified key was too long; max key length is 767 bytes

    操作重现: 法1:新建连接——>新建数据库——>右键数据库导入脚本——>提示:Specified key was too long; max key length is 767 by ...

  4. 如何用easyui+JAVA 实现动态拼凑datagrid表格

    先给大家看一看效果,最近一段时间都在研究这个东西. 如果我把日期间隔选宽呢?比如5月日到5月5日?下面给大家看看效果,不用担心哦 看到了吧,哈哈,这个日期都是动态生成的,下面就来跟大家分享一下这个的实 ...

  5. DatePickerDialog、AutoCompleteTextView

    DatePickerDialog选择日期,调用showDialog(int id)方法,会执行onCreateDialog方法: @Override protected Dialog onCreate ...

  6. 【JUC】JDK1.8源码分析之ConcurrentHashMap(一)

    一.前言 最近几天忙着做点别的东西,今天终于有时间分析源码了,看源码感觉很爽,并且发现ConcurrentHashMap在JDK1.8版本与之前的版本在并发控制上存在很大的差别,很有必要进行认真的分析 ...

  7. 【Java基础】并发

    Num1:同步访问共享的可变数据 关键字Synchronized可以保证在同一时刻,只有一个线程可以执行某一个方法,或者某一个代码块.. 同步不仅仅理解为互斥的方式,如果没有同步,一个线程的变化就不能 ...

  8. git安装和初次使用

    为了知道某人安装git,我也是重装啊. 1.下载git并安装 2.打开我的电脑,右键属性,选择高级设置,打开环境变量设置: 3.键盘输入窗口键+r,或者点击开始->运行 输入cmd 在新打开的命 ...

  9. JavaScript中的数据类型转换

    本文中提到的“原始值”指的是undefined,null,Boolean,string和number. 本文中的对象是native对象,宿主对象(浏览器定义的对象)按照各自的算法转换. JavaScr ...

  10. sealed、new、virtual、abstract与override 趣解

    1. sealed——“断子绝孙” 密封类不能被继承.密封方法可以重写基类中的方法,但其本身不能在任何派生类中进一步重写.当应用于 方法或属性时,sealed修饰符必须始终与override一起使用. ...