數據庫引擎-分區表上的查詢和維護

分區表是將一個很大的表按照某列的值分成若干個部分進行存儲。舉例來說,證券交易所需要保存每天的交易記

錄,估計每天交易量需要1G的存儲量,而數據庫只保存最近90天的數據,其餘數據保存在磁帶上。這樣我們就可

以將目標表按照數據日期分成90個分區。當第91的數據到來時,將第一天的數據切除。正如我們在之前的文章中

所描述的那樣,每個分區對應於一個分配單元。而對整個存儲單元的添加或刪除操作是對元數據的操作,不會涉

及到IO,因此是非常快的。同時使用分區表還有利於優化查詢性能,就像本文說要討論的那樣,數據庫引擎針對

分區表做了特殊的處理。

對分區表上聚集索引的掃描不同於普通表。系統會在用戶創建的聚集索引列前添加用來做分區的列。當系統根據

查詢條件掃描索引樹的時候,首先它根據分區列的值找到特定的分區,然後利用剩餘的條件匹配索引的其他列。

舉例來說,您有一個Transaction(DayId,User,...)表,DayId是用來分區的列,而在user上建有聚集索引。

面對如下查詢時:
select * from Transaction where DayId in (20090101,20090102) and User='Smith'
系統首先找到20090101對應的分區,在這個分區上找到user='Smith'的行;然後去20090102的分區上繼續查找,

最後組合結果。

當查詢需要對兩個具有相同分區列的表進行Jion的時候,例如A表和B表,系統會生成多個線程,分別將A表的分

區和B的分區進行Join。由於不需要將整個表裝載到內存中,這種方法可以減少IO的發生,從而提高性能。

如果系統中有較多的可用線程,而又需要對分區表進行查詢的時候,系統儘量在各個分區上平均分配工作線程,

以減少分區之間的順序查詢造成的等待。

爲了提高分區表的效率,我們通常要考慮使用更多的磁盤驅動器,以允許多個線程同時進行IO操作;更大的內存

以減少IO的發生;更多更快的CPU,以提高查詢的速度。同時我們還需要考慮對錶和索引進行壓縮,以減少內存

佔用的空間;對分區創建聚集索引,以便於使用B-樹進行掃描。

在向分區表添加大量數據時,常用的方式是:創建一個和目標表一樣結構的臨時表,將數據考入其中;在表上創

建聚集索引和Constraints;使用Alter-Switch的方式將這個臨時表加入目標表。但上述的方法僅僅適用於新加

的數據恰好是一個分區的情況,要知道SQL Server只允許1000個分區。如果您每天添加一天的數據,而目標表的

一個分區是一個星期的話,您可以考慮一下的方式:
1. 新來的一天的數據直接插入到這個星期對應的分區上;
2. 創建一個新的表,該表有7個分區,存放7天的數據,當7天填滿時,合併到目標表;
3. 創建一個普通表,每天的數據按照普通的方式插入,最後合併到目標表。
清注意到普通的插入方式很可能導致在插入數據的時候,不能進行查詢。請根據目標表的實際需求選擇適當的加
載方式。

發佈了36 篇原創文章 · 獲贊 0 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章