转自:微软技术大会2016
逐行插入:插入数据-》行组 超过100K 102400行才会插入到压缩行组-》压缩行组-》移动元组-》列段
大批量插入:插入数据 超过100K 102400行-》压缩行组-》移动元组-》列段
数据插入到行组时,一旦并发度过高,会临时生成多个临时行组,临时行组最后会合并为一个行组
插入数据-》行组 (行组会有X锁行锁)影响并发
两种方式
建表时候直接创建一个聚集列存储索引表
建表时候先建一个普通聚集索引表,然后在这个普通聚集索引表上建立一个聚集列存储索引(一个聚集索引表变成了两个副本两份数据,一个是聚集索引,一个是聚集列存储索引)
SQL2014:聚集列存储索引表不能建立主键,不支持有大对象数据类型nvarchar(max)等的表
SQL2016:聚集列存储索引表可以建立主键,支持有大对象数据类型nvarchar(max)等的表
http://mysql.taobao.org/monthly/2017/03/04/
delta store->列存储
看这篇文章之前可以先看一下下面这两篇文章:
列存储索引
http://www.cnblogs.com/qanholas/archive/2013/03/08/2949205.html
非聚集索引
http://www.cnblogs.com/lyhabc/p/3196484.html
还有这一篇文章
https://www.sqlpassion.at/archive/2017/01/30/columnstore-segment-elimination/?awt_l=BJCrA&awt_m=3mFjBb8vbIYUUTS
行组-》加密,压缩-》元数据,段-》blob段数据列存储
东方瑞通
一张表水平切为多个行组,各个行组有垂直切为多个段,每个小方块为一个段(一个表又水平切又垂直切成多个小方块(段))
段列中的部分行的一个集合
包含相同行的段是一个行组
数据以段为单位进行压缩
每个段存储在不同lob页中
段是IO访问的最小单位
建立测试环境
先创建一张表
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 --全表扫描
列存储索引的结构
先创建一张表保存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 )