SQL Server Column Store Indeses

SQL Server Column Store Indeses

SQL Server Column Store Indeses. 1

1. 概述... 1

2. 索引存储... 2

2.1 列式索引存储... 2

2.2 数据编码和压缩... 3

2.2.1 编码... 3

2.2.2 优化行顺序... 4

2.2.3 压缩... 4

2.3 I/O和Cache. 4

3 查询处理和优化... 4

3.1 查询处理加强... 4

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

时间: 2024-10-16 10:26:36

SQL Server Column Store Indeses的相关文章

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 2016 Contents About This Guide...................................................................................... 11 Shared Topics in This Guide .

SQL Server 列存储索引强化

SQL Server 列存储索引强化 SQL Server 列存储索引强化... 1 1. 概述... 1 2.背景... 2 2.1 索引存储... 2 2.2 缓存和I/O.. 2 2.3 Batch处理方式... 2 3 聚集索引... 3 3.1 提高索引创建... 4 3.2 采样的支持... 4 3.3 BookMark的支持... 4 3.4 其他加强... 4 4 更新处理... 4 4.1 随机插入... 6 4.2 批量插入... 6 4.3 删除和更新... 6 4.4 对

《Pro SQL Server internals》翻译

本文选自<Pro SQL Server Internals> 作者: Dmitri Korotkevitch 出版社: Apress 出版年: 2016-12-29 页数: 804 作者简介:Dmitri Korotkevitchis是微软SQL Server MVP和微软认证大师.作为应用程序和数据库开发人员.数据库管理员和数据库架构师,他具有多年使用SQL Server的经验.他专门从事OLTP系统在高负载下的设计.开发和性能调优.Dmitri经常在各种Microsoft和SQL PASS

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

传统的关系数据库服务引擎往往并不是对超大量数据进行分析计算的最佳平台,为此,SQL Server中开发了分析服务引擎去对大笔数据进行分析计算.当然,对于数据的存放平台SQL Server数据库引擎而言,也是需要强大的数据处理能力的. 在SQL Server 2012时,SQL Server 引入了列存储索引,用以显著提供高传统数据仓库类型语句的性能,并在SQL Server 2014中做了进一步加强.本文将在对SQL Server 2012列存储索引简单介绍的基础上,进一步解释SQL Serve

sql server query to get the list of column name in a table

--SQL Server 2005, 2008 or 2012: SELECT * FROM information_schema.tables --SQL Server 2000: SELECT * FROM sysobjects WHERE xtype='U' SELECT * FROM sysobjects WHERE xtype='U' SELECT TABLE_NAME FROM geovidnu.INFORMATION_SCHEMA.Tables SELECT sobjects.na

SQL Server -&gt;&gt; SQL Server 2016新特性之 --- Query Store

前言 SQL Server 2016引入新的查询语句性能监控.调试和优化工具/功能 -- Query Store.以前我们发现一条查询语句性能突然下降,我们要去找出问题的所在往往需要通过调用一些DMV(比如sys.dm_exec_query_stats, sys.dm_exec_sql_text和sys.dm_exec_query_plan)来获取查询计划的一些信息,比如XML格式的执行计划,查询语句的代码,执行了多少次以及一些资源和时间的的使用消耗情况.然后根据这些信息来判断这条语句是否存在性

07 SQL Server中的Identity列(Identity Column in SQL Server)

如果创建新表的时候将一个列设置为Identity,那么在插入数据的时候可以不显示的指定值,SQL Server会自动填充该列的值. Create Table tblPerson1 ( PersonId Int Identity(1,1) Primary key Not Null, Name Nvarchar(50) null ) 此时,可用下面的代码向表中插入数据.虽然tblPerson表有两列,但在插入的时候只用指定Name的值即可,因为PersonId的属性为Identity,在插入数据时S

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

如何在SQL Server查询语句(Select)中检索存储过程(Store Procedure)的结果集?(2006-12-14 09:25:36) 与这个问题具有相同性质的其他描述还包括:如何在SQL Server存储过程中获取另一存储过程的执行结果记录集?如何在存储过程中检索动态SQL语句的执行结果?如何实现类似SELECT * FROM (EXEC procedure_name @parameters_var) AS datasource ... 的功能?procedure_

Reset Identity Column Value in SQL Server (Identity Reset)

前言:今天在群里看到有人在问SQL Server自增值重置问题(sqlserver identiy column value reset ) 闲话少说,直接上代码: 正文: --create table --create test table if not exists(select * from sysobjects where name = 'Test_1') begin create table Test_1 (ID int identity(1,1) primary key,Name n