65.9K
CodeProject 正在变化。 阅读更多。
Home

列存储索引

starIconstarIconstarIconstarIconstarIcon

5.00/5 (3投票s)

2012年2月23日

CPOL

7分钟阅读

viewsIcon

25681

downloadIcon

159

列存储索引

引言

  • 列存储索引由微软的 VertiPaq 技术运行。

  • 对于行存储索引,多个页面将包含跨越多个页面的多行。对于列存储索引,多个页面将包含多个单列。这将导致只从磁盘中获取解决查询所需的列。此外,单列中很可能存在冗余数据,这将进一步有助于压缩数据,这将对缓冲区命中率产生积极影响,因为大部分数据将驻留在内存中,因此无需检索。
  • https://bineeshthomas.wordpress.com/2011/10/07/what-is-vertipaqctp3-denali-sql-server/

    VertiPaq 使列存储索引更高效,因为它采用与传统索引不同的列存储方式,并有效地压缩了索引中的数据。在常规索引中,每行中所有索引数据都存储在单个页面上,并且每列中的数据分布在索引中的所有页面上。在列存储索引中,每列中的数据存储在一起,因此每个数据页面只包含来自单个列的数据。此外,每列的索引数据都经过压缩,由于许多列通常包含高度重复的值,因此压缩比可以非常高。这种架构减少了索引中的页面数量,并且如果您只选择少数列,它还会减少需要扫描的页面数量(因此 SQL Server 更有可能将它们保留在内存中)。

无索引

SQL Server parse and compile time: 
CPU time = 0 ms, elapsed time = 0 ms. 
SQL Server parse and compile time: 
CPU time = 0 ms, elapsed time = 9 ms. 

(1 row(s) affected) 
Table 'BitTable'. Scan count 9, logical reads 278294, physical reads 0, 
read-ahead reads 243609, lob logical reads 0, lob physical reads 0, 
lob read-ahead reads 0. 

SQL Server Execution Times: 
CPU time = 21247 ms, elapsed time = 69118 ms. 

无列存储索引(有普通索引)

SQL Server parse and compile time: 
CPU time = 0 ms, elapsed time = 12 ms. 

(1 row(s) affected) 
Table 'BitTable'. Scan count 9, logical reads 153430, physical reads 0, 
read-ahead reads 99164, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 

SQL Server Execution Times: 
CPU time = 14929 ms, elapsed time = 46018 ms. 

有列存储索引

SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 9 ms. 

(1 row(s) affected)
Table 'BitTable'. Scan count 8, logical reads 752, physical reads 1, read-ahead reads 296, 
lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 

SQL Server Execution Times: 
CPU time = 11714 ms, elapsed time = 2977 ms. 

列存储结构

列存储数据物理上存储在每列的一个或多个(常规 LOB 分配单元)中,并且也可以以通常的方式进行分区。每个段包含大约一百万行高度压缩的值或值引用(有几种压缩技术可用)。值引用链接到最多两个哈希字典中的一个条目。

在查询执行期间,字典会固定在内存中,每当执行需要实际数据值时,就会在字典中查找来自段的数据值 ID(出于性能原因,此查找会尽可能延迟)。

段还具有一个包含元数据(例如段中存储的最小值和最大值)的头部记录。头部记录中的信息通常可用于在执行时消除完整的分区。头部记录信息存储在常规 LOB 数据根结构中,因此消除段意味着存储引擎可以完全跳过从物理存储读取 LOB 数据页。最大限度地发挥消除潜力可能需要精心设计,包括在构建列存储索引时对聚集索引顺序的依赖

特定计划操作符

SQL Server 2012 引入了一种名为批处理模式的新执行模式。在此模式下,大约 1000 行的数据包在操作符之间传递,显著提高了处理器利用效率。在每个数据包中,列式数据表示为一个向量。并非所有计划操作符都支持批处理模式操作,但支持的示例包括列存储索引扫描、哈希内连接、批处理哈希表构建、位图过滤器、哈希聚合(不是标量聚合)、过滤器和计算标量(用于投影和表达式评估)。

列存储索引没有行;相反,它使用 BLOB 存储来存储列“段”。由于列式存储可以进行压缩,它只需要聚集索引所需页面的大约三分之一,尽管它包含相同的列和相同数量的事实。

BLOB(二进制大对象)

BLOB(二进制大对象)是一个大型文件,通常是图像或声音文件,由于其大小,必须以特殊方式处理(例如,上传、下载或存储在数据库中)。

SQL Server 将 BLOB 数据存储为 8KB 页面的集合,并将其组织在 B 树结构中。每行的 BLOB 列都包含一个 16 字节的指针,指向根 B 树结构,该结构跟踪构成 BLOB 的各个数据块。如果二进制数据量小于 64 字节,SQL Server 会将其作为根结构本身的一部分存储。否则,根结构由一系列指针组成,SQL Server 使用这些指针来定位构成二进制对象的数据块。

逻辑读和物理读

http://www.sql-server-performance.com/2010/logical-reads/

“SQL Server 实例的 I/O 分为逻辑 I/O 和物理 I/O。每次数据库引擎请求缓冲区缓存中的页面时,都会发生逻辑读。如果页面当前不在缓冲区缓存中,则执行物理读以将页面读入缓冲区缓存。如果页面当前在缓存中,则不会生成物理读;缓冲区缓存只是使用已在内存中的页面。”

重要的是要记住,SQL Trace 读取是逻辑读取,而不是物理读取。

逻辑读、物理读和缓冲区缓存命中率

  • 逻辑读:从缓存读取数据页
  • 物理读:从硬盘读取数据页
  • 缓冲区缓存命中率 = (逻辑读 – 物理读) / 逻辑读 * 100%

逻辑读

逻辑读表示从数据缓存中访问以处理查询所需的数据页总数。逻辑读很可能会多次访问相同的数据页,因此逻辑读值可能高于表中实际的页面数。通常,减少逻辑读的最佳方法是应用正确的索引或重写查询。

物理读

物理读表示从磁盘读取的数据页总数。如果数据缓存中没有数据,则物理读将等于逻辑读的数量。这通常发生在第一次查询请求时。对于后续相同的查询请求,由于数据页已在数据缓存中,该数字将大幅减少。

缓冲区缓存命中率

缓冲区命中率将根据这两种读类型按照以下公式计算:(逻辑读 - 物理读) / 逻辑读 * 100%。高缓冲区命中率(如果可能接近 100%)表明 SQL Server 级别的数据库性能良好。因此,使用物理读和缓冲区命中率的信息来衡量服务器级别性能,并使用逻辑读来衡量单个查询级别性能。

垂直分区:示例

行存储和列存储

行存储 列存储
易于添加/修改记录 只需读取相关数据
可能会读取不必要的数据 元组写入需要多次访问

为什么选择列存储?

  • 仅获取查询所需的列
  • 更好的缓存效果
  • 更好的压缩(列内相似的属性值)

列存储索引的优势

  1. 由于列存储索引存储在单独的页面中,因此只从磁盘中获取所需的页面
  2. 更快的查询处理
  3. 频繁访问的列保留在内存中
  4. 增强的查询优化和执行功能,在某些情况下可将数据仓库查询性能提高数百到数千倍

B 树

B 树是一种在数据库中放置和定位文件(称为记录或键)的方法。(字母 B 的含义尚未明确定义。)B 树算法最大限度地减少了访问介质以定位所需记录的次数,从而加快了过程。

当决策点(称为节点)位于硬盘而非随机存取存储器 (RAM) 中时,B 树更受青睐。

B 树通过使用具有许多分支(称为子节点)的节点来节省时间,与每个节点只有两个子节点的二叉树相比。当每个节点有许多子节点时,可以通过更少的节点找到记录,而不是每个节点只有两个子节点。

在树中,记录存储在称为叶子的位置。这个名称源于记录总是存在于端点的事实;它们后面没有其他东西。

历史

  • 2012 年 2 月 21 日:初始版本
© . All rights reserved.