我应该在什么时候拆分或分区一个非常大但简单的表

Mar*_*nox 11 performance sql-server

我们的网站有一些大而简单的(INT、INT、DATE)统计表。每个表最多有 300,000,000 行,而且每天都在变大。

托管服务提供商建议我们拆分或分区表,我在其他地方多次看到此建议。

然而...

我正在努力将这个建议与SQL Server规定的最大容量相协调——数据库大小为 524,272 TB,表行仅受“可用存储”的限制。

根据这些数字,上面描述的表格很容易有数百万计的行(10 的 303 次方)。

啊哈哈,你可能会说,能力和性能是有区别的。

几乎所有关于 SQL Server 性能的问题的答案都是“这取决于......取决于表设计和查询设计”。

这就是我问这个问题的原因。桌子的设计再简单不过了。基于索引 ID 字段的简单 count(*) 操作查询也不能。

Ben*_*hul 11

一般建议是有原因的,因为它取决于表设计和对它的查询。我对在 Stack Exchange 上的其他帖子的回答也说明了这一点。说“基于索引 ID 字段的简单 count(*) 操作的查询”并没有提供太多信息,因为它没有说明所考虑的行集的基数。您可以采取的措施来缓解(目前认为的)问题:

  1. 分区。具体来说,您的数据似乎是日志类型的数据。我的猜测是您想按某个时间单位(例如“每天的小部件”或“每小时的whozits”)获得统计数据。按您的量程(即前面示例中的数天或数小时)进行分区,并偶尔将分区移至只读文件组

  2. 在相关说明中,如果数据是一次性写入的,请考虑在时间段不再活动时预先聚合数据。也就是说,如果数据永远不会改变,为什么我需要继续计算三年前一天发生的事件数量?一天结束后,把当天所有的东西都数一遍,存放在别处,再也不数了。事实上,如果您从不需要详细数据(即您只对它进行聚合),请考虑在计算后将其删除。如果你实现了这个想法,你可以更聪明地使用只覆盖“活动”期间的过滤索引,这将使你的查询更快,因为它们不会覆盖你的绝大多数数据

但是,正如我在另一篇文章中的建议所暗示的那样,您确定知道的唯一方法是加载合理数量的数据并进行尝试。我们在这里所能做的就是说明在一般情况下可能会起作用的方法。如果没有您的硬件、数据和查询的详细信息,我们所能做的就是猜测。而且,您可能会发现,一旦您运行测试,我建议的答案是“没有什么可做的”,因为它按原样运行得很好。


Tho*_*ser 8

在决定分区的大小之前,请考虑分区的查询计划含义。从纯粹的性能角度来看,分区充当粗粒度索引的一种形式。这可以提供额外的性能,但它也是性能回归的根源,特别是如果分区键没有出现在所有查询中。从这里开始,我假设您已经完成了这项作业(看起来您已经完成了)。

您想要的分区大小的一个很好的经验法则是:大约是您在盒子上拥有的 DRAM 大小的一半。提出这个建议的原因是:

  1. 您可以重建分区上的索引而不会溢出到tempdb. 这比使用磁盘访问(即使使用 SSD)要快得多。
  2. 在进行此重建时,您仍然可以在 DRAM 中保存整个分区(通常是最新的),以保持查询性能良好地运行。

换句话说,你想要有足够的 DRAM 来容纳两个分区,你想要的分区大小取决于你运行的机器。更大的机器可以轻松处理更大的分区。

请注意,本指南还提供了以下各项的最小大小tempdb: 至少是最大分区的大小(因此,如果在重建索引时没有足够的 DRAM,您可以将索引构建溢出到那里)。

您可能会考虑比这更小的分区大小,但如果您这样做,这通常是为了性能优化而不是支持数据的可管理性。

您可以使用分区玩很多其他技巧。例如,在只读分区上压缩、聚合或使用填充因子 100。但基本原则仍然是:尽量让你管理的每一块数据都小于 DRAM。

PS:很高兴看到您不以“视情况而定”作为答案,总是寻求获得答案的方法。


swa*_*eck 7

我将采用不同的方法并注意分区(在 SQL Server 中)主要是一种数据管理功能,查询性能可能是次要结果,具体取决于您的管理方式1

如链接文章中所述,分区的主要好处是您可以使用分区切换快速移动数据。例如,您可以将“较冷”的数据归档到较慢的存储中,并将“热”的数据保存在较快的存储中。在定期安排的时间间隔内,您可以通过将数据滚动到存档分区来快速存档数据,而无需经历等待 ETL 执行传输的过程。但是,正如对您的问题的早期评论之一所指出的,这需要实施之前进行一些仔细的思考和计划。此外,根据您使用的 SQL Server 版本(企业),您可以利用数据压缩来压缩单个分区。

就性能而言,您可以将锁升级更改为AUTO(默认为TABLE),如下所示

ALTER TABLE dbo.T1 SET (LOCK_ESCALATION = AUTO);
GO
Run Code Online (Sandbox Code Playgroud)

此外,您可能会消除分区,但您的查询模式需要适合系统中非常具体且可重复的模式 -分区键和集群键以及任何唯一键变得相互关联且非常重要。如果这种平衡没有得到承认和设计,你最终会遇到性能噩梦。

随着 SQL Server 2014 的出现,您还可以利用增量统计信息,如果您主动监视和更新/创建大型表的统计信息,这将非常方便。

那么,应该在什么时候对表进行分区?这取决于您的查询工作负载和数据的配置文件,但最重要的是,这取决于您绝对必须利用的分区管理功能。分区不是为了查询性能,它主要是为了数据管理和管理。

  • “分区不是为了查询性能,它主要是为了数据管理和管理”——你这么说似乎很明显,但我以前从未完全明白。伟大的链接顺便说一句,谢谢 (2认同)

Sol*_*zky 7

表分区,像其他几个功能一样,经常(甚至可能是最常使用?)使用不当。我会给出的任何警告都在@swasheck 的回答中得到了很好的说明。

此外,要考虑的替代方案是分区视图。这是一种保持完全独立的表,但通过视图中的 UNION ALL 将它们链接在一起的方法。每个表都需要一个 CHECK CONSTRAINT 来强制每个表保存的数据范围。优化器知道这个构造并且应该只访问使用视图的查询所需的基础表(我不记得按预期进行这项工作的所有要求,所以请参阅底部的 CREATE VIEW 链接,但是我之前已经设置过它,让它按预期工作并不难)。

肯定有一些限制,主要的缺点是与表分区相比,它的透明度较低。但是,一个主要的好处是它们是单独的表,因此统计信息是完全独立的,而对于分区表,它们是针对整个表的(即使从 SQL Server 2014 开始,您可以更新每个分区的统计信息)。

如果您不打算使用切入和切出分区,则应考虑此选项。特别是如果较旧的数据变化不大,因为保存较旧数据的表不需要它们的索引/统计数据几乎经常更新(或者如果数据永远不会改变,则可能永远更新)。

表分区的另一个经常未被提及/未被注意到的缺点是,从 SQL Server 2012 开始,在重建分区索引时,您不再获得“免费”的 UPDATE STATISTICS WITH FULLSCAN。您仍然可以通过在非分区索引上重建来获得此更新统计信息,分区视图中表上的索引将是:)。

有关分区视图的更多信息,请查看CREATE VIEW的 MSDN 页面并查找“备注”下的“分区视图”部分。

  • 关于 UPDATE STATISTICS 的要点。如果您可以处理优化器的影响,索引视图可以解决很多分区问题。 (2认同)