【问题标题】:Partitioning for query performance in SQL Server 2008SQL Server 2008 中的查询性能分区
【发布时间】:2011-05-14 00:58:00
【问题描述】:

我有一个场景,其中有大量关于某个项目的状态数据。 项目状态每分钟更新一次,近期大概有50,000个项目。因此,在一个月内,将有大约 2,232,000,000 行数据。在归档旧数据之前,我必须在主表中至少保留 3 个月。

我必须计划基于特定项目(其 ID)和数据范围(通常最多一个月)来实现快速查询 - 例如从表中选择 A、B、C,其中 ItemID = 3000 和日期在 '2010-10-01' 和 '2010-10-31 23:59:59.999' 之间

所以我的问题是如何设计一个分区结构来实现这一点?

目前,我正在根据“项目的唯一标识符”(int)mod“分区数”进行分区,以便所有分区均等分布。但它的缺点是在表上保留一个额外的列作为分区函数的分区列,因此,将行映射到其分区。所有这些都增加了一点额外的存储空间。此外,每个分区都映射到不同的文件组。

【问题讨论】:

  • 这有点负担。阅读here 关于大量写入的信息(您有 50k 行每秒传入)。我很想知道你将如何解决这个问题:我根本没有这种数量/增长率的经验
  • 你是想为写查询效率设计还是读查询效率?你有什么样的读取负载?
  • 您能否向我们提供更多关于表格中的列以及您在查询中返回的列大小(宽度)的信息?

标签: sql-server


【解决方案1】:

永远不会为了查询性能而进行分区。使用分区,性能总是会变差,你可以期望的最好的结果是没有大的回归,但永远不会改善。

对于查询性能,分区可以做的任何事情,索引可以做得更好,这应该是您的答案:适当的索引。

分区对于 IO 路径控制案例(在存档/当前卷上分布)或 ETL 负载中的快速切换场景非常有用。因此,如果您有一个滑动窗口和按日期分区,我会理解,这样您就可以快速切换不再需要保留的数据。

另一种狭义的分区情况是最后一页插入锁存器争用,如Resolving PAGELATCH Contention on Highly Concurrent INSERT Workloads 中所述。

您的分区方案和用例似乎不适合它会受益的任何场景(也许是最后一个场景,但从描述中不清楚),所以很可能会受到伤害性能。

【讨论】:

  • 我将此分区表解决方案与另一个未分区的表进行了比较,分区解决方案的结果稍差(98ms vs 99ms)我使用了8个分区,现在,我会尝试改为使用 250 个,分布在 2 个驱动器中,看看情况如何。
  • Poco - 两 (2) 个驱动器,生产系统中是否只有两个驱动器?
【解决方案2】:

我不太同意 Remus Rusanu 的观点。我认为如果有逻辑原因(与您的用例相关),分区可能会提高性能。我的猜测是您只能在 itemID 上进行分区。另一种方法是也使用日期,但如果您无法预测日期范围不会跨越给定分区的边界(没有查询肯定是一个月),那么我会坚持使用 itemId 分区。

如果您只需要计算几个项目,另一种选择是有一个覆盖索引:在您的主要区分字段(itemId)上定义一个索引,其中包括您需要计算的字段。

CREATE INDEX idxTest ON itemId INCLUDE quantity;

【讨论】:

    【解决方案3】:

    应用分区实际上可以提高查询性能。在您的情况下,您有 50K 项和 2G 行。例如,您可以创建 500 个表,每个名为 status_nnn,其中 nnn 介于 001 和 500 之间,并在这些表中平均“划分”您的项目状态,其中 nnn 是项目 ID 的函数。这样,给定一个项目 ID,您可以先验地将搜索限制为整个数据的 0.2%(大约 4M 行)。

    这种方法有很多缺点,因为您可能必须处理动态 sql 和其他令人不快的问题,尤其是当您需要聚合来自不同表的数据时。但是,它肯定会提高某些查询的性能,s.a.你提到的那些。

    本质上,应用分区类似于创建一个非常宽且平坦的索引,针对非常具体的查询进行了优化,无需复制数据。

    应用分区的另一个好处是,理论上(取决于您的用例)您可以将数据分布在不同的数据库甚至不同的服务器之间。同样,这在很大程度上取决于您的具体要求,但我已经看到并处理过大量数据集(数十亿行),其中应用分区运行良好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-01
      • 1970-01-01
      • 2016-08-10
      • 1970-01-01
      • 2020-02-21
      • 2011-01-30
      相关资源
      最近更新 更多