13

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

4

6 回答 6

6

我认为通过在单个服务器中跨多个数据库对表进行分区,您不会真正获得任何收益。您所做的一切基本上都增加了使用“表”的开销,方法是在单个 SQL Server 实例下拥有多个实例(即在两个不同的数据库中打开)。

你有多大的数据集?我有一个客户端,在 SQL Server 中有一个 600 万行的表,其中包含 2 年的销售数据。他们将其用于交易和报告,没有任何明显的速度问题。

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

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

于 2008-10-03T19:30:58.603 回答
3

分区不是一件轻而易举的事情,因为可能会产生许多微妙的性能影响。

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

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

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

如果您对数据分区(包括分区到多个文件组)感兴趣,那么我建议您阅读 Kimberly Tripp 的文章,他在 SQL Server 2005 发布时就该处可用的改进进行了出色的演示。一个很好的起点是这份白皮书

于 2008-10-03T19:39:11.800 回答
2

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

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

过去(2005 年之前)我不得不对表进行分区时,通常是按日期列或类似的东西,以查看各个分区。Books Online 有一个部分讨论如何执行此操作以及围绕它的所有规则。您需要遵守规则,使其按应有的方式工作。

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

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

于 2008-10-03T19:23:09.167 回答
1

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

在设计方面... 回到过去,有时需要垂直分区来解决数据库引擎的限制,其中表中的列数是硬性限制,例如 255 列。如今,主要好处纯粹是为了提高性能:将很少使用的列或 blob 放在单独的磁盘阵列上。但是,如果您经常从两张桌子上取东西,那可能会是一种损失。听起来您的潜在客户正遭受过早优化的困扰。

在告诉你的领导是错误的方面......这需要外交。如果他意识到在性能方面的不满,那么基准可能是显示差异的最佳方式。

使用“create table t1 as select * from view1”在某处创建一个新的物理表,然后使用垂直分区表和新表运行一些冗长的批处理。如果它像你说的那么糟糕,那么差异应该是显而易见的。

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

于 2008-10-03T19:37:13.413 回答
1

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

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

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

这就是为什么现在由于数据库处理的数据量很大,明智的做法是设计应用程序,使查询受到时间、地理位置等更广泛的组的限制,以便在选择此类列时分区您将获得最大的收益。

于 2010-05-05T17:22:46.320 回答
0

我不同意分区不能获得任何东西的假设。

如果分区数据在物理和逻辑上是对齐的,那么查询的潜在 IO 应该会大大降低。

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

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

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

我没有在 SQL Server 上做过很多分区,但我确实有在 Sybase ASE 上进行分区的经验,这就是所谓的分区消除。当我有时间时,我将在 SQL Server 2005 机器上测试该场景。

于 2009-07-01T14:47:41.777 回答