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 對查詢處理的影響... 6
5 查詢處理和優化... 6
5.1 混合執行模式... 7
5.2 Hash Join. 7
5.2.1 spilling. 7
5.3 Bitmap過濾... 7
6 歸檔壓縮... 7
7 性能測試... 8
7.1 Batch模式性能... 8
7.2 存儲需求... 9
7.3 刪除性能... 9
7.4 批量和隨機插入... 9
參考:... 9
1. 概述之前SQL Server只有2個存儲組織方式,heaps和Btree,都是基于行的。SQL Server 2012之后加入了新的存儲方式是,列存儲壓縮方式。還加入了新的查詢處理方式,batch處理。
在SQL Server 2012中有不少限制,會在之后的版本中被修正:1.列存儲索引可更新。2.可以當主存儲方式用,比如聚集索引。3.可以進一步壓縮,減少使用空間。4.batch處理方式得到很大的擴展和加強。
2.背景2.1 索引存儲如圖演示了列存儲索引是如何創建和保存的。注意在列存儲索引中數據是不排序的。在一個columnsegment也沒有排序。如圖中顯示,segment和目錄會被以blob的方式保存每個column segment和目錄都以獨立的blob保存。一個blob可能分布在不同的磁盤page上,但是是有blob機制自動控制的。
目錄保存了segment位置的信息,所以所有segment包含了一個列和任何相關的目錄信息可以被簡單的定位。目錄也包含了額外的元數據。
2.2 緩存和I/OColumn segment和目錄根據需要會被加載到內存中。但是并不會被保存在bufferpool中,有一個新的cache用來緩存large objects。每個對象連續的被保存在內存頁中沒有空隙,提高掃描性能。為了提高I/O性能預讀可以再segment中進行,也可以再segment間進行。
2.3 Batch處理方式SQL Server傳統使用行模式,新的查詢操作有些引入了batch模式。
一個batch通常是由幾千行組成,如圖,每個列被保存在連續的元素長度固定的向量上。Batch的執行方式效率很高,比如執行col1<5過濾,只需要掃描col1的向量比較執行,并且設置在qualifying row向量上的bit位。
SQL Server 2012只對一些操作符支持了batch模式,如Hash join的batch實現有2個操作,一個是build,一個是實際的join操作。在build階段,多線程并發創建一個hashtable,每個線程只處理一個子集,一旦build完成,多線程并發PRobe表,每個線程處理一部分probe輸入。因為join的輸入不會預先分配,所以會導致數據傾斜問題使幾個線程負荷不均。
Cpu在hash join上的減少很顯著,行模式每行要用600個指令,但是batch模式只需要85個指令。
優化器會決定使用行模式還是batch模式。Batch模式通常被用在數據密集計算,行模式通常使用在小輸入,計算在樹上完成,或者不支持batch操作的地方。
3 聚集索引在SQL Server2012中,列存儲只能以secondary 索引方式存在,之后的版本SQL Server會取消這個限制。并且允許列存儲來組織表數據。
3.1 提高索引創建SQL Server列存儲使用另一種目錄來編碼。在經常出現的值上,使用32bit對應到目錄上。SQL Server使用2種目錄,一個是全局目錄和整個列相關,一個是局部目錄,只和當前rowgroup相關。
修改了創建索引的過程,現在過程分為2步:1.采集每個列的數據,然后決定是否要為這個列創建一個全局的目錄,并選一些數據放入到全局目錄上。2.使用第一步生成的全局目錄來創建一個索引。
列存儲的創建過程是很耗內存的,因此會在創建之前先保留好內存,根據保留的內存和每個線程需要的內存決定線程個數。初始的內存評估是不準確的,因為內存分配和數據有關很難準確評估。為了解決這個問題,使用動態的決定活動的線程個數來解決,build過程會監控內存的消耗來決定活動線程個數。
3.2 采樣的支持SQL Server的優化器使用數據分布的統計信息來優化查詢。統計信息是一個直方圖,由隨機采樣活得。非聚集的列存儲索引不需要支持采樣,因為統計信息可以通過基表活得。
統計信息的采樣有2種方式:1. 不太準確的,對io,cpu要求不高。2. 準確的,io,cpu開銷較大。
性能優化的采樣掃描使用集群采樣,即,一組rowgroups會被隨機選擇,行的掃描取決于采樣率。沒有被選中的rowgroups不會被讀取。從btree和heap上采樣也使用聚集采樣的方式。
第二種方式是真實的隨機行級別的采樣。掃描所有的列并且隨機選擇一些行的子集。這樣采樣會比btree和heap上采樣要準確。列存儲的聚集采樣只是用來幫助目錄的創建,不會被用于查詢優化。
3.3 BookMark的支持在SQL ServerBookMark是一個術語唯一的標示一行。在SQL Server中任何索引都可以被bookmark定位。最多的應用是在刪除操作上,刪除的時候會先收集bookmark然后在實際刪除行之前先刪除bookmark。因為列存儲索引沒有key來唯一標示一行,所以我們使用唯一標示row group中一行的tupleid和row group id組合來唯一標示使用。
3.4 其他加強SQL Server 2012對某些列不支持,后續版本會對這部分類型支持,對于字符串,以后支持保存短字符串的值,而不是轉為32bit的id。
4 更新處理列存儲對讀取性能提升很大,但是直接對數據修改花費也很大。列存儲的設計目的是數據倉庫的事實表,通常有大量的insert,刪除和更新很少。老的數據定期刪除可以通過分區切換實現,高性能的常規插入和批量插入比較關鍵。
SQL Server使用了2個組件來自持列存儲可更新:delete bitmap和delta stores。
每個列存儲索引都有一個關聯的deletebitmap,在掃描disqualify rows的時候會去查詢bitmap過濾被刪除的行。在內存和磁盤上bitmap結構是不同的,在內存中是bitmap,但是在磁盤上則是btree。
插入的或者修改的會被插入到deltastore,delta store是btree行模式存儲。Delta store對列存儲掃描是透明的。
有了這些組件,列存儲的增刪改就可以實現了:insert:直接把新行插入到delta store,因為是btree所以可以高效的完成delete:若行被刪除會把包含一個rowid的記錄保存到保存了delete bitmap的btree中。如果行在delta store比較簡單可以直接從btree中刪除。update:update操作會被分為delete和insertmerge:Merge操作也會被分為delete,insert或者update操作。
Delta store和對應的列存儲有的列是一樣的。唯一鍵是rowid由系統生成。
列存儲可能有多個deltastore,當有行要插入的時候,會創建新的delta store。Delta store到達上限之后就會關閉。SQL Server會自動檢查關閉的delta store并把它們轉化為列存儲的方式。處理這個的任務被稱為Tuple Mover,定期的在后臺運行,不會堵塞讀,但是會堵塞刪除。
Tuple Mover讀取一個關閉的deltastore,開始創建相關的壓縮segment,當創建完新的segment會被設置為可見,相關的delta store就不可見了。Tuple Mover等delta store上的掃描都完成之后就會刪除這個delta store。
4.1 隨機插入通常非批量插入,在這里都稱為隨機插入。插入到列存儲對查詢處理是透明的。有內部的訪問方法層負責deltastore的處理。
4.2 批量插入大的bulk insert不會把行直接插入到delta store而是直接把一批行轉化為列存儲。這個操作會緩存行,直到累計的行數滿足可以轉化為列存儲的條件,并把結果segment和目錄寫入到磁盤。這個很有效減少IO的需求。
當bulk insert完成的時候,必須壓縮并且關閉數據,bulk insert API中的batch_size是指一次bulk insert的行數。為了提高壓縮效率,建議把batch size設置為1MB。
雖然有時候batchsize很大但是無法滿足壓縮row group的條件,SQL Server會自動的把這些行放入delta store。
4.3 刪除和更新對于刪除操作,會直接把刪除行的rowid寫入到delete bitmap 上。Update操作則為被分為insert和delete 2個部分。
4.4 對查詢處理的影響Delta store和deletebitmap的控制是由訪問方法層處理的,對查詢處理層透明。
在掃描列存儲時,發現rowid存在在delete bitmap那么這個行就會被跳過,這個操作也是在訪問方法層處理,對查詢處理器透明。
The process of segment elimination during scans (by checkingsegment metadata containing the minimum and maximum values in columns) does notneed to consult the deleted bitmap. The interval between the minimum andmaximum values within a column cannot grow when rows are deleted. Therefore,the original minimum and maximum values computed during column store segmentcreation can safely be used for segment elimination even after deletes.
有大量的delete會減少io的性能,因為delete bitmap 會變大。
并發掃描deltastore是為每個delta分配一個線程,因為一個delta store并發掃描會顯得delta store 太小。Delta store的掃描比列存儲掃描慢,因為delta store是列存儲會讀入不必要的列。
5 查詢處理和優化在SQL Server2012中Batch處理之應用在大量查詢的數據倉庫的場景。batch處理圖形比較呆板,join循序是根據基數評估確定。當內存無法滿足要求是,會使用行模式執行。
之后的SQL Server版本,Batch處理有更強的能力。會考慮執行計劃中的迭代器的batch執行,不管輸入是不是使用batch執行的,不管數據的組織方式是列還是行。并且join的循序不再固定。Batch操作支持所有的join類型,unionall,標量聚集。
如圖計劃是混合模式的,紅色框框是行模式處理。
5.1 混合執行模式在SQL Server 行和batch之間轉化由計劃規定,轉化只有在必要的情況下才會發生。后續版本的SQL Server會有全新的模式來處理行和batch之間的轉化。
5.2 Hash Join一開始只有innerjoin支持,現在已經支持所有join類型。
必須要有足夠的內存來創建hash表,如果沒有就會從batch模式轉化為row模式可以支持低內存情況下運行,通過把數據spilling到磁盤來降低內存使用。
提高了bitmap過濾的實現。
5.2.1 spilling以簡單的join為例,hash join的spill:Build階段:在build之前數據通過hash函數被分為若干個buckets。當決定spill的,選擇一個bucket然后標記為spilling,創建一個新的臨時文件,并把bucket數據寫入到文件中并釋放內存。Probe階段:在處理probe時,不對
新聞熱點
疑難解答