SQL Server 2014 聚集列存儲


  SQL Server 自2012以來引入了列存儲的概念,至今2016對列存儲的支持已經是非常友好了。由於我這邊線上環境主要是2014,所以本文是以2014為基礎的SQL Server 的列存儲的介紹。下面我們主要看一下列存儲的發展以及一些原理:

列存儲的開發是想要處理超大量數據進行分析計算,於是在SQL Server 2012時,SQL Server 引入了列存儲索引,用以顯著提供高傳統數據倉庫類型語句的性能,並在SQL Server 2014中做了進一步加強。列存儲會將一個列的數據單獨存放在一起,所以主要會有以下兩個優點。

1:同一個列中的數據的相似性比較高,因此壓縮比例會更高。磁盤操作時,磁盤的IO也會相應的降低。當然,當壓縮的數據讀取到內存后解壓會需要額外的CPU。

2:由於數據是按照列進行存儲和讀取的,因此如果某些列在訪問中並不需要,那么實際的操作時也會不訪問這些列,那么磁盤IO會進一步降低。

3:由於數據是按照列進行存儲和讀取的,大批量的數據聚合訪問等會較以往的行存儲更快。

對於列存儲來說,主要來說就是數據倉庫這個使用場景了,微軟最近幾年也是在這個方面頻頻發力。對於數據倉庫來說,CPU,內存,磁盤都可能稱為性能的瓶頸,但是我們指導磁盤的操作來說相比內存和CPU性能是最慢的,而列存儲恰恰是對IO的性能提升是很大的,列存儲會減少磁盤的IO操作,提升運算的效率,特別是大量數據的聚合。當然如果是一些線上的精確查找等操作,列存儲並不是最好的選擇。

  對於這些性能的提升和存儲 空間的優化,主要是和列存儲的實現原理是分不開的(由於非聚集列存儲的功能比較雞肋,我們就不介紹了,因為有非聚集列存儲的表成為了一個只讀表):

1:Clustered columnstore inde – 整個表都按照列存儲進行組織,直接替代了傳統的堆表或者聚集索引,可以自由的進行增刪改操作。

2:聚集列存儲索引雖然相對於非聚集列存儲索引在column store這塊組織架構基本一樣,但是它可以進行增刪改操作。原因是它多了一塊或者多塊行存儲部分,這部分稱之為delta tore。

新插入的數據是直接加載到delta store中的刪除操作只是將數據標識為刪除,實際的刪除需要在rebuild時完成。更新操作會拆分為一個刪除操作和一個插入合並完成。
如果一個bulk insert的批次插入的量小於100000,那么數據會加載到delta store中,否則會加載到columnstore中。
當delta store中數據量超過100 0000后,“Tuple mover” 會將其中數據進行歸總放置到column store中。貼一個官方圖,方便更好的理解聚集列存儲:

原理大概看完之后,下面給出SQL Server2014對列存儲的改進:

● 支持數據的讀和寫
● 在打破了數據只讀的限制后,列存儲索引使用的范圍和場景大大增加
● 相比傳統的ad-hoc的增刪改操作,在SQL Server2014還是推薦使用bulk insert和分區交換來進行大批次數據的更新,效率更高,維護成本也會降低
● 支持更多的數據類型
● 添加了更多的數據類型支持:(n)varchar(max), varbinary(max), XML, Spatial, CLR
● 基本說來,SQL Server2014的列存儲支持所有的non-blob數據類型
● 整個表可建立並且只能建立一個聚集列存儲索引。傳統的行存儲會需要非聚集索引幫助提高訪問效率,但是列存儲無需這樣。並且由於只有一份數據,因此存儲需要的磁盤空間大大降低
● 非聚集列索引仍然支持,並且還是只讀的結構。
當我們有了聚集列存儲索引后,就不需要非聚集列索引了,因為此時所有的數據都是按照列存儲了。但是如果表上需要添加Constraints或者工作負載仍然需要B-tree形式的非聚集索引,那么我們還是只能考慮使用非聚集列存儲索引。
● 語句的執行上有以下改進
○ 基於矢量的計算方式得到改
○ 支持更多的語法
■ 所有的join方式(包括OUTER, HASH, SEMI (NOT IN, IN)
■ UNION ALL
■ Scalar aggregates
■ “Mixed mode” plans
● 對bitmap和spill操作有進一步的改進
● 對hash join有所改進

  其實我在SQL Server 2014列存儲的實踐當中,還發現有幾個不是非常友好的地方

1:SQL Server 2014聚集列存儲並不支持視圖功能,這個還是比較坑的,因為列存儲的主要應用場景就是數據倉庫,有很多視圖來說要提供報表或者提供給報表部門查詢權限,通過視圖能夠隱藏很多敏感信息,而不支持視圖就會很難做決定來具體修改為列存儲了

2:SQL Server 2014聚集列存儲並不支持alwayson從庫的查詢

3:SQL Server 2014  12.0.2版本對列存儲有漏洞,alwayson日志同步的時候容易造成內部鎖爭用,影響主從的同步,這點功能我們可能要升級SP1補丁才能解決,我這邊從庫升級后至今沒有出現這個問題,這也是SQL Server 2014列存儲的一個BUG吧

以上也算是在生產環境走過的坑,因為考慮不是很周全走了不少路。希望大家能夠引以為戒。除了以上幾個坑以外,列存儲還不支持以下的功能

在列存儲索引中不可使用以下數據類型:
binary(n)、varbinary(n)(在2014及更高版本中允許使用,但不包括varbinary(max)),image、text、ntext、varchar(max)、nvarchar(max),sql_variant,xml
只能通過刪除及創建索引的方式重建索引,而不可使用ALTER INDEX命令
在視圖或索引視圖中無法使用列存儲索引
列存儲索引無法結合使用以下特性:分發,變更數據捕獲,變更追蹤,Filestream
列存儲索引不可包含多於1024個列
對應的表不可包含唯一性約束、主鍵約束或外鍵約束

接下來我們看一下列存儲的一些實踐:

1:創建列存儲的表

CREATE TABLE maxiangqian( 
id [int] NOT NULL, 
age [int] NOT NULL, 
sex [tinyint] NOT NULL, 
name varchar(20)); 
GO 
CREATE CLUSTERED COLUMNSTORE INDEX cci_Simple ON maxiangqian; 
GO :

2:行聚集索引轉換為列存儲:

CREATE TABLE maxiangqian( 
id [int] NOT NULL, 
age [int] NOT NULL, 
sex [tinyint] NOT NULL, 
name varchar(20)); 
GO 
CREATE CLUSTERED INDEX cl_simple ON maxiangqian (id); 
GO 
CREATE CLUSTERED COLUMNSTORE INDEX cl_simple ON maxiangqian 
WITH (DROP_EXISTING = ON);

或者說我們也可以直接刪除聚集索引,然后再

CREATE CLUSTERED COLUMNSTORE INDEX cl_simple ON maxiangqian 

效果是一樣一樣的。

3 將一個堆表轉化為列存儲表:

第一步就是刪除堆表現有的索引,然后創建聚集列存儲索引:

CREATE TABLE maxiangqian(  
    id [int] NOT NULL,   
    age [int] NOT NULL,   
    sex [tinyint] NOT NULL,   
    name varchar(20));  
GO  
create index pid on maxiagnqian(id)

drop index pid on maxiangqian 

CREATE CLUSTERED COLUMNSTORE INDEX cci_Simple ON maxiangqian;  
GO  :

上面基本上已經滿足你建立列存儲的一些功能,下面我們看一下怎么把一個聚集列存儲的表轉化為普通表:

CREATE CLUSTERED INDEX pid   ON maxiangqian  
WITH ( DROP EXISTING = ON );  
或者
DROP INDEX cci_Simple   ON MyFactTable; 

OK,我們基本上已經可以知道怎么創建列存儲索引了

但是我們指導由於列存儲刪除的時候只是標記,所以說列存儲如果經常更新刪除,碎片還是會很大的,下面我們看下怎么消除碎片---重建:

CREATE CLUSTERED COLUMNSTORE INDEX cci_Simple   ON maxiagnqian  
WITH ( DROP_EXISTING = ON );  


ALTER INDEX   cci_Simple ON maxiangqian REBUILD PARTITION = ALL  
WITH ( DROP_EXISTING = ON );  

以上兩種方式是都可以實現的。

其實對於列存儲來說,卧鋪,我這邊給我比較大的驚喜就是磁盤空間的節約,列存儲的壓縮比例可以達到10:1甚至15:1,而且相對來說對於我數據倉庫一些大批量的聚合操作性能提升。在節省空間又提高性能的情況下,你還有什么理由不選用列存儲呢。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM