数据库引擎-分区表上的查询和维护

来源:互联网 发布:java对象实例化 编辑:程序博客网 时间:2024/06/07 07:59

分区表是将一个很大的表按照某列的值分成若干个部分进行存储。举例来说,证券交易所需要保存每天的交易记

录,估计每天交易量需要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. 创建一个普通表,每天的数据按照普通的方式插入,最后合并到目标表。
清注意到普通的插入方式很可能导致在插入数据的时候,不能进行查询。请根据目标表的实际需求选择适当的加
载方式。

原创粉丝点击