转自:微软技术大会2016

SQLSERVER2012 列存储索引的简单研究和测试

逐行插入:插入数据-》行组 超过100K 102400行才会插入到压缩行组-》压缩行组-》移动元组-》列段

大批量插入:插入数据  超过100K 102400行-》压缩行组-》移动元组-》列段

数据插入到行组时,一旦并发度过高,会临时生成多个临时行组,临时行组最后会合并为一个行组

 

插入数据-》行组 (行组会有X锁行锁)影响并发

SQLSERVER2012 列存储索引的简单研究和测试

两种方式
建表时候直接创建一个聚集列存储索引表
建表时候先建一个普通聚集索引表,然后在这个普通聚集索引表上建立一个聚集列存储索引(一个聚集索引表变成了两个副本两份数据,一个是聚集索引,一个是聚集列存储索引)

SQL2014:聚集列存储索引表不能建立主键,不支持有大对象数据类型nvarchar(max)等的表
SQL2016:聚集列存储索引表可以建立主键,支持有大对象数据类型nvarchar(max)等的表

 

 

http://mysql.taobao.org/monthly/2017/03/04/

delta store->列存储

SQLSERVER2012 列存储索引的简单研究和测试

 

 

看这篇文章之前可以先看一下下面这两篇文章:

列存储索引

http://www.cnblogs.com/qanholas/archive/2013/03/08/2949205.html

非聚集索引
http://www.cnblogs.com/lyhabc/p/3196484.html

还有这一篇文章

SQLSERVER中的LOB页面简单研究

 

https://www.sqlpassion.at/archive/2017/01/30/columnstore-segment-elimination/?awt_l=BJCrA&awt_m=3mFjBb8vbIYUUTS

行组-》加密,压缩-》元数据,段-》blob段数据列存储

SQLSERVER2012 列存储索引的简单研究和测试

 

东方瑞通

一张表水平切为多个行组,各个行组有垂直切为多个段,每个小方块为一个段(一个表又水平切又垂直切成多个小方块(段))
段列中的部分行的一个集合
包含相同行的段是一个行组
数据以段为单位进行压缩
每个段存储在不同lob页中
段是IO访问的最小单位

SQLSERVER2012 列存储索引的简单研究和测试

SQLSERVER2012 列存储索引的简单研究和测试


建立测试环境

 先创建一张表

 1 USE [pratice]
 2 GO
 3 IF (OBJECT_ID('TestTable') IS NOT NULL)
 4 DROP TABLE [dbo].[TestTable]
 5 GO
 6 CREATE TABLE TestTable
 7 (
 8     id INT  ,
 9     c1 INT  
10 )
11 GO


插入1W条测试数据

1 DECLARE @i INT
2 SET @i=1
3 WHILE @i<10001
4 BEGIN
5 INSERT INTO TestTable (id,c1)
6 SELECT @i,@i
7 SET @i=@i+1
8 END
9 GO


看一下插入的记录是否足够

1 SELECT COUNT(*) FROM TestTable
2 SELECT TOP 10 * from TestTable

在C1列上创建一个列存储索引

1 CREATE NONCLUSTERED columnstore INDEX PK__TestTable__ColumnStore ON TestTable(c1)

执行计划

在上面给出的文章里提到 http://www.cnblogs.com/qanholas/archive/2013/03/08/2949205.html

下面几个SQL语句的执行计划也显示出列存储索引不会seek

(2)列存储索引不支持 SEEK

如果查询应返回行的一小部分,则优化器不大可能选择列存储索引(例如:needle-in-the-haystack 类型查询)。

如果使用表提示 FORCESEEK,则优化器将不考虑列存储索引。

 

1 SELECT * FROM TestTable WHERE [C1]=60  --列存储索引扫描 RID查找
2 SELECT id FROM TestTable WHERE [C1]=60  --列存储索引扫描 RID查找
3 SELECT c1 FROM TestTable WHERE [C1]=60   --列存储索引扫描
4 SELECT * FROM TestTable WHERE id=60   --全表扫描
5 SELECT c1 FROM TestTable --列存储索引扫描
6 SELECT * FROM TestTable   --全表扫描

SQLSERVER2012 列存储索引的简单研究和测试

SQLSERVER2012 列存储索引的简单研究和测试

SQLSERVER2012 列存储索引的简单研究和测试

 SQLSERVER2012 列存储索引的简单研究和测试

SQLSERVER2012 列存储索引的简单研究和测试

SQLSERVER2012 列存储索引的简单研究和测试


列存储索引的结构

先创建一张表保存DBCC的结果

 1 USE [pratice]
 2 GO
 3 CREATE TABLE DBCCResult (
 4 PageFID NVARCHAR(200),
 5 PagePID NVARCHAR(200),
 6 IAMFID NVARCHAR(200),
 7 IAMPID NVARCHAR(200),
 8 ObjectID NVARCHAR(200),
 9 IndexID NVARCHAR(200),
10 PartitionNumber NVARCHAR(200),
11 PartitionID NVARCHAR(200),
12 iam_chain_type NVARCHAR(200),
13 PageType NVARCHAR(200),
14 IndexLevel NVARCHAR(200),
15 NextPageFID NVARCHAR(200),
16 NextPagePID NVARCHAR(200),
17 PrevPageFID NVARCHAR(200),
18 PrevPagePID NVARCHAR(200)
19 )
View Code

相关文章:

  • 2021-11-30
  • 2022-01-08
  • 2021-05-23
  • 2021-12-07
  • 2022-01-07
  • 2022-01-08
  • 2022-12-23
猜你喜欢
  • 2021-08-16
  • 2022-02-25
  • 2021-05-25
  • 2022-12-23
  • 2022-12-23
  • 2021-09-24
相关资源
相似解决方案