在SQL Server中分区大表的最佳方法是什么?

问题描述 投票:13回答:6

在最近的项目中,“主要”开发人员设计了一个数据库模式,其中“较大”的表将分成两个独立的数据库,主数据库上的视图将两个单独的数据库表联合在一起。主数据库是应用程序的驱动因素,因此这些表看起来像普通表(除了一些有关更新的古怪事物)。这似乎是一个巨大的性能问题。我们确实看到围绕这些表格的性能问题,但没有什么可以让他改变他对他的设计的看法。只是想知道最好的方法是什么,或者它是否值得做?

sql sql-server partitioning
6个回答
6
投票

我不认为你真的会通过在单个服务器中跨多个数据库划分表来获得任何收益。所有你基本上完成的工作都是通过在单个SQL Server实例下拥有多个实例(即在两个不同的DB中打开)来增加使用“表”的开销。

你有多大的数据集?我有一个客户端,在SQL Server中有一个600万行表,包含2年的销售数据。他们在事务上使用它并报告没有任何明显的速度问题。

当然,调整索引并选择正确的聚簇索引对性能至关重要。

如果您的数据集非常大并且您正在寻找分区,那么您将获得更多的优势,可以在物理服务器上对表进行分区。


3
投票

分区不是轻易进行的,因为可能会有许多微妙的性能影响。

我的第一个问题是你是指简单地将较大的表对象放在单独的文件组中(在不同的主轴上),还是指的是表对象内部的数据分区?

我怀疑所描述的情况是试图将某些大表的物理存储放在其他表的不同主轴上。在这种情况下,添加单独数据库的额外开销,失去在数据库之间强制实施参照完整性的任何能力,以及启用跨数据库所有权链接的安全隐患,与在单个数据库中使用多个文件组相比,没有任何好处。如果很可能,您在问题中引用的单独数据库甚至不存储在单独的主轴上,而是存储在同一主轴上,那么即使您通过物理分离磁盘活动可能获得的轻微性能优势也可以抵消绝对没有受益。

我建议您不要使用其他数据库来保存大型表,而是查看SQL Server联机丛书中的文件组主题或快速查看,请参阅此article:

如果您对数据分区感兴趣(包括分区到多个文件组),那么我建议您阅读Kimberly Tripp撰写的文章,他们在SQL Server 2005发布时提供了一个很好的演示文稿,介绍了可用的改进。一个好的起点是这个whitepaper


2
投票

您使用的是哪个版本的SQL Server? SQL Server 2005具有分区表,但在2000(或7.0)中,您需要使用分区视图。

另外,将表分区放在单独的数据库中的原因是什么?

当我不得不在过去(2005年之前)对表进行分区时,它通常是通过日期列或类似的东西来查看各个分区。联机丛书有一节介绍如何执行此操作以及围绕它的所有规则。您需要遵循规则,使其工作原理。

要记住的关键是您的分区列必须是主键的一部分,并且您希望在对表的任何访问中始终使用该列,以便优化器可以忽略不应受查询影响的分区。

在MSDN中查找“分区表”,您应该能够找到更完整的SQL Server 2005分区表教程,以及如何设置它们以获得最佳性能的建议。


1
投票

您是在询问数据库设计方面的最佳实践,还是说服您的主角改变主意? :)

在设计方面...回到goode olde时代,有时需要垂直分区来解决数据库引擎限制,其中表中的列数是一个硬限制,如255列。目前,主要的好处纯粹是为了提高性能:将很少使用的列或blob放在单独的磁盘阵列上。但是,如果你经常从两个牌桌上抽出东西,那么很可能是亏损。听起来你的领导正在遭遇过早优化的情况。

告诉你的领导是错的......这需要外交。如果他意识到对表现不满的嘀咕,基准可能是展示差异的最佳方式。

使用'create table t1 as view * from view1'在某处创建一个新的物理表,然后使用垂直分区表和新表运行一些冗长的批处理。如果它和你说的一样糟糕,差异应该很明显。

但这也可能是过早的优化。了解最终用户对性能的看法。如果性能足够好,对于一些好的定义,那么就不要修复那些没有破坏的东西。


1
投票

表分区有一个明显的好处(无论它是在相同或不同的文件组/磁盘上)。如果正确选择了分区列,您将意识到您的查询将仅访问所需的分区。所以想象一下,如果你有1亿条记录(我已经将表格分区了大得多 - 大约20多亿行),而且大多数情况下,超过70%的数据访问只是某个类别,时间轴或类型然后,它有助于将访问最多的数据保存在单独的分区中。此外,您可以将分区与具有各种类型磁盘(SATA,光纤通道,SSD)的单独文件组对齐,以便最快/最繁忙的数据位于最快的存储上,而最少/很少访问的数据实际上位于较慢的磁盘上。

虽然,在SQL Server中,分区能力有限,与Oracle不同。您只能选择一列进行分区(即使在SQL 2008中)。因此,您必须明智地选择列,其中该列也是大多数常见查询的一部分。在大多数情况下,人们发现按日期列选择分区很容易。但是,尽管以这种方式划分似乎是合乎逻辑的,但如果您的查询没有将该列作为条件的一部分,则您将无法从分区中获得足够的好处(换句话说,您的查询将无论如何都会遇到所有分区)。

对数据仓库/数据挖掘类型数据库进行分区要比OLTP容易得多,因为大多数DW数据库查询都受到时间段的限制。

这就是为什么这些天由于数据库处理数据的大小,明智的做法是设计应用程序,使得查询受到某些更广泛的组(如时间,地理位置等)的限制,以便在选择此类列时分割你将获得最大的利益。


0
投票

我不同意通过分区无法获得任何东西的假设。

如果分区数据在物理上和逻辑上对齐,则应大大减少查询的潜在IO。

例如,我们有一个表,其批处理字段为INT,表示INT。

如果我们按此字段对数据进行分区,然后重新运行特定批次的查询,我们应该能够在分区之前和之后运行set statistics io ON并查看IO的减少,

如果我们每个分区有一百万行,并且每个分区都写入一个单独的设备。查询应该能够消除不必要的分区。

我没有在SQL Server上进行过大量的分区,但我确实有在Sybase ASE上进行分区的经验,这称为分区阻止。当我有时间我将在SQL Server 2005机器上测试场景。

© www.soinside.com 2019 - 2024. All rights reserved.