什么是数据库分区?
数据库分区是一种对表的横向分割,Sql server 2005企业版和之后的Sql server版本才提供这种技术,这种对表的横向分割不同于2000中的表分割,它对访问用户是透明的,用户并不会感觉的表被横向分割了。(2000中的表横向分割是建n个表例如按时间建表每月一个表,表名不同,最后需要做一个大视图)
关于具体的如何做分区,请参考数据库分区演练http://www.cnblogs.com/yukaizhao/archive/2008/05/07/sql_partition_test.html
为什么要分区?
显而易见分区是为了提高数据库的读写性能,提高数据库的效率;
分区是否总是可以提高效率?
分区是一把双刃剑,并不总能提高效率,这和具体情况有关系。
之所以有分区技术,分区技术用的好的话可以提高性能,是因为一方面分区把一大块数据分成了n小块,这样查询的时候很快定位到某一小块上,在小块中寻址要快很多;另一方面CPU比磁盘IO快很多倍,而硬件上又有多个磁盘,或者是RAID(廉价磁盘冗余阵列),可以让数据库驱动CPU同时去读写不同的磁盘,这样才有可能可以提高效率。
分区在有些时候并不能提高读写效率,比如说我们经常看到的按照日期字段去分区MSDN例子,这个实例中是按照记录的生成时间来分区的,把一年的数据分割成12个分区,每月一个。这样的分区导致分区并不能实现CPU同步写并提高写入性能,因为在同一个时段CPU总是要写入到最新的那一个分区对应的磁盘中。另一个问题是:这样分区是否可以提高读取性能呢?答案是不一定,要看根据什么字段来查询,如果是根据时间来查询,根据时间生成报表那么这种分区肯定会提高查询的效率,但是如果是按照某个客户查询客户最近1年内的账单数据,这样数据分布到不同的分区上,这样的话效率就不一定能提高了,这要看数据在同一个分区上连续分布的读性能高,还是CPU从几个磁盘上同步读取,然后在合并数据的性能更高一些,这和读取数据的记录数也有关系。
如何分区?用什么字段做分区依据?
具体如何分区和涉及的业务有关系,要看业务上最经常的写入和读取操作是什么,然后再考虑分区的策略。
既然与具体业务相关,我们就假定一个业务环境,假如我们要做一个论坛,对论坛的帖子和回复表进行分区。
论坛中最常见的写操作是1)发帖 2)回复帖子,
最常见的读操作是
1) 根据帖子id显示帖子详情和分页的帖子回复
2) 根据帖子版面帖子列表页根据版面id分页读取帖子列表数据
怎么分区更合适呢?现在还没有准确答案,我有两种可能的方案,写下来,大家讨论看看。
方案1. 根据帖子ID区域段分区(1-300w一个分区、300w-600w一个分区…),这样理论上可以提高帖子详细页的读取速度,而对于写操作性能没有益处,对于根据版面id读取帖子列表页有可能有益
方案2. 根据版面id进行分区,这样对于写性能应该有提高,不同的分区对应不同的版面,当有两个版面同时有发帖回帖操作时,有可能可以并发写。对于根据版面id获得帖子列表页数据也可以提高性能,而对于帖子详细信息页没有性能影响。
多大的数据量才需要分区?
这个问题我只能说一个内部标准,如果一张表的记录超过在超过1000w,并以每月百万的数据量增长,那就需要分区。大家有不同的看法请回复讨论
关于具体的如何做分区,请参考数据库分区演练http://www.cnblogs.com/yukaizhao/archive/2008/05/07/sql_partition_test.html
posted @ 2008-11-27 10:01
玉开 阅读(5362)
评论(51) 编辑 收藏
评论
对于数据库分区,我本人也没有多少经验,以上多是理论之谈,请大家给出自己的看法。批评指点都是欢迎的。
@玉开
大哥是有所不知啊,SQL小弟很菜啊,所有的东西都只处于 很菜 的阶段,慢慢来,我不急,也不慢. 急不来,送不下 呵呵
不过每天都把首页的东西看完了的,虽然我不写(不是我不写,是还不会写字)
数据在同一个分区上连续分布的读性能高,还是CPU从几个磁盘上同步读取,然后在合并数据的性能更高一些
我就想知道这个,,,因为分区只能根据一个列来划分,,,
这样对于其他的一些查询就需要跨区进行,,,这样对效率有无影响??
@xuzhibin1
(msdn中的介绍)
可以通过以下两种方式之一将现有的无分区表转变为已分区表。
一种方式是通过使用 CREATE INDEX 语句对表创建已分区聚集索引。此操作类似于对任一表创建聚集索引,因为 SQL Server 实质上将删除表并以聚集索引格式重新创建该表。如果已经对表应用了某个已分区聚集索引,则可以使用带有 DROP EXISTING = ON 子句的 CREATE INDEX 删除该索引并以某种分区方案重新生成该索引。
有关聚集索引的信息,请参阅聚集索引设计指南。
另一种方式是使用 Transact-SQL ALTER TABLE SWITCH 语句将表中的数据切换到只有一个分区的按范围分区的表中。此已分区表在转换发生之前必须已经存在,并且该表的单个分区必须为空。有关切换分区的详细信息,请参阅使用分区切换高效传输数据。将表修改为已分区表之后,可以修改其分区函数以增加分区,如前面修改分区函数中所述。
对于第一种方式,,然后重建索引就行了,如果聚焦索引是主键,需要先去掉外键,可以用类似下面的语句解决,,
IF EXISTS (SELECT name FROM sys.indexes
WHERE name = N'PK_mb_Product')
alter table [mb_Product] drop constraint [PK_mb_Product]
GO
ALTER TABLE [mb_Product] WITH CHECK ADD
CONSTRAINT [PK_mb_Product] PRIMARY KEY CLUSTERED
(
productid
) ON product_partscheme (productid);
谢谢楼上各位解答,再问一个,如果我在一个已经数据的分区表上修改分区函数,原先在A区的数据会不会跑到B区上(新的数据按规则是应该加到B上的)?
@Cheney Shue
谢谢,我回去看看。
不过感觉你的说法有点武断了
--引用--------------------------------------------------
xuzhibin1: 谢谢楼上各位解答,再问一个,如果我在一个已经数据的分区表上修改分区函数,原先在A区的数据会不会跑到B区上(新的数据按规则是应该加到B上的)?
--------------------------------------------------------
这个不清楚,可以弄张简单的表,做个试验呀。
--引用--------------------------------------------------
Cheney Shue: <span style="font-size: 14pt">分区不是这么简单的,建议你去看看<a href="http://download.oracle.com/docs/cd/B28359_01/server.111/b32024/toc.htm">VLDB and Partitioning Guide</a>。<br />
另外,还建议你换一种数据库,SQL Server的分区是一个非常搞笑的功能,增加了管理负担,降低了性能。</span>
--------------------------------------------------------
楼主在实际项目中使用过sql server 的分区吗?如果使用过,请说下怎么用的?
@Cheney Shue
你不就是在用Oracle嘛..
@rO8eR70.nEt
@wingoo
@Cheney Shue
其实不管什么样的数据库,都是需要优化的。Sql server需要,Oracle也需要,两者有很多相通之处。大家多探讨如何优化吧。
不是绝对,在真实的环境中用过就知道sql server的分区不切实际。
要带来真正实惠的功能才是有用的,sql server很多功能只是个噱头,还不如不要。
@Cheney Shue
可否讲一下你是如何用sql server分区的,你的业务是怎样的。有可能是你的做法有问题,分区本来就是双刃剑,用好了可以提高性能,用不好会损害性能。
Oracle的分区也不会对一个表的所有查询都提高性能。
@Cheney Shue
分区本身会根据键值和分区方案将记录分布到不同的物理磁盘上,如果可以提高插入性能,就有可能对某种查询性能不利,需要根据业务权衡如何使用。
--引用--------------------------------------------------
玉开: @Cheney Shue
可否讲一下你是如何用sql server分区的,你的业务是怎样的。有可能是你的做法有问题,分区本来就是双刃剑,用好了可以提高性能,用不好会损害性能。
--------------------------------------------------------
它不能实现我想要的,所以我不用它。不光是性能问题。
--引用--------------------------------------------------
玉开: @Cheney Shue
分区本身会根据键值和分区方案将记录分布到不同的物理磁盘上,如果可以提高插入性能,就有可能对某种查询性能不利,需要根据业务权衡如何使用。
--------------------------------------------------------
如果分区仅仅是为了将数据分布在不同的磁盘上提高性能,那我用Raid就可以了,何必要分区呢
@Cheney Shue
不知道你有什么特殊功能,会有ms sql server实现不了的功能。理论上来说oracle和sql server都是关系数据库,oracle可以实现的,sql server也可以实现。
当然oracle数据库比sql server出现的早,它有优势,但是从业务上来说都是关系数据库,没什么实现不了的。
我建议你先去看看那个文档,弄明白为什么要分区,再去参照看SQL Server是否能做到。
分区之所以能提升性能,主要是由于Partition Pruning和Partition-Wise Joins。SQL Server不能实现。
SQL Server没有最常用的Hash分区、复合分区和参照分区等。如果Table分区了,Index必须是local分区,这是非常不合理的。
所以我说SQL Server的分区不是提升性能,而是降低性能。只有像你说的将分区存储在不同的磁盘上才可能提升性能,但已不适用现在的Raid环境。
SQL Server缺少针对分区的操作,可管理性差。
除了性能,分区另一个目的是信息生命周期管理,这要求分区提高数据的可管理性和可用性。但SQL Server的分区却是在增大管理的难度。
SQL Server缺少针对分区的操作。也没有ASM,分区是跟物理结构挂钩的。一个大型数据库,经常需要增加或淘汰存储设备。在SQL Server里面,如果你一个大型表有50个分区就够麻烦的了,如果这样的表有10个。。。
oracle 又和 sql serverl 干上了.不知道是谁被洗脑了.
现阶段还没有处理这么大的数据的机会
不过先了解了
玉开每个工作日都会写博客,很难得啊
@Cheney Shue
我会认真看下你说的那两个资料,不过我不会武断的怀疑微软那么多顶级开发人员的智商。什么事物都有一个发展过程,ms sql server是,oracle也是。
@Jerry Qian
大家互相了解一下各个不同产品的长处是有好处的,没有谁被洗脑
--引用--------------------------------------------------
玉开: @Cheney Shue
sql server 可以实现Hash分区的,只不过需要多建一个hash的列,这个列是一个生成列,checksum(另一个列)
<a href="http://it.newnew.cn/it39275.aspx" target="_new">http://it.newnew.cn/it39275.aspx</a>
--------------------------------------------------------
当然可以hash分区,但不能Partition-Wise Joins和Partition Pruning有什么用,只是降低性能而已
--引用--------------------------------------------------
玉开: @Cheney Shue
我会认真看下你说的那两个资料,不过我不会武断的怀疑微软那么多顶级开发人员的智商。什么事物都有一个发展过程,ms sql server是,oracle也是。
--------------------------------------------------------
不要相信厂商的宣传,事实上ms sql server就是这么弱智,随便就可以说出一大堆问题。
@Cheney Shue
就算没有你说的那两个特性也不会只是降低性能的,起码它把表横切了,分而治之了,在某些查询上肯定可以提高性能的。
ms sql 2000中根本没有分区的概念,但是开发人员依然可以把表横切来提高性能。
--引用--------------------------------------------------
玉开: @Cheney Shue
就算没有你说的那两个特性也不会只是降低性能的,起码它把表横切了,分而治之了,在某些查询上肯定可以提高性能的。
ms sql 2000中根本没有分区的概念,但是开发人员依然可以把表横切来提高性能。
--------------------------------------------------------
为什么会提高性能?我用Raid,数据本身就分散在各个存储设备上,何必用这样的方式呢。
降低性能是很明显的,试试就知道。
比如你的表按照ID字段分区,再在这个表上对SKU字段加一个unique index,因为sql server的索引只能是local partition的,就是说跟表使用同样的分区方式。
当你insert一行数据时,根据ID值,数据被insert到table_partition1,但需要验证SKU索引的唯一性,会从SKU索引所有分区的根部开始扫描。这样的效率显然不如用非分区索引或者全局分区索引快。
@Cheney Shue
sql server中可以单独为索引指定是否采用和表分区相同的文件组,也就是说索引可以和表分区对齐,也可以不对齐。
--引用--------------------------------------------------
玉开: @Cheney Shue
sql server中可以单独为索引指定是否采用和表分区相同的文件组,也就是说索引可以和表分区对齐,也可以不对齐。
--------------------------------------------------------
我说的不是文件组问题
@Cheney Shue
玉开说有时会提高查询性能,但你非要拿插入时的情况来说明会降低性能我觉得
似乎是牛头不对马嘴!
如果你说sql的分区在你面对的应用中99%的时候是垃圾,我相信!
如果是按日期。自增Id等做分区依据,的确没啥分区的必要,
比较可行的方法,还是读写分离
Cheney Shue其实说得没有错。SQL Server的数据分区现在看来就是做得很失败的一个东西,要性能没有性能、要维护效率没有维护效率,仅仅只是为了和
Oracle来竞争,做了一个相同的概念。
因为数据分区实现上的开销,在TPC-E这样的大负荷测试之下,读写性能和不开启数据分区时,要下降30%之多。但现在已经做成这样,要改进看来是很难了。
lz,你文章第1句话,好像有点遗漏:
“数据库分区是一种对表的横向分割”
数据库分区实际上有横向和纵向2种,纵向分区用得少
@aierong
纵向实质是将表拆分成2个或以上
@xianerz
哪儿不懂呢?或许是没写明白