表分区能提高性能吗?这值得么?

Hau*_*uri 7 performance sql-server partitioning query-performance

我刚刚参与了一个项目,我必须在该项目上开发一个数据迁移过程和一个使用现有 SQL Server 数据库的 Web 界面。这个数据库是几年前由另一个人开发的,它有大约 100 GB 的数据,并且每 10 分钟增加一次(它存储来自多个单元的 10 分钟数据 -> 每个设备每天 144 条记录)。几个表有大约 1000 万行。关键是我认为主表的设计方式不是最有效或最适合通常执行的查询类型的方式。现在我需要证明我所说的是否比已经实施的更好。DB 表的数量很庞大,但可以通过下图简化结构: 在此处输入图片说明

Date_Id 字段由使用 DateTime 字段的函数自动生成。两个表中都有两个索引。每个表的簇索引包含相同顺序的 PK 字段。Unit 表的第二个索引仅包含 Unit_Id 字段,而 UnitData 中的第二个索引按此顺序包含 Unit_Id 和 DateTime 字段。

但是,我认为设计应该是这样的: 在此处输入图片说明

在这种情况下,只需要 PK 字段的聚集索引。对于此数据库设计,通常的查询类似于:

SELECT ud.*
FROM Unit u, UnitData ud
WHERE u.Unit_Id = ud.Unit_Id and ud.DateTime >= 'dd-MM-yyyy'
ORDER BY ud.Unit_Id, ud.DateTime
Run Code Online (Sandbox Code Playgroud)

现在出现了我真的不明白的事情:有人告诉我,拥有 Date_Id 列的唯一原因是将其用作该表的分区列。我问过对这个表进行分区的真正必要性,答案是“在需要每日或每月数据时更有效地运行查询”。在此之前我不太了解分区,所以我检查了这些链接:

http://msdn.microsoft.com/en-us/library/ms190787.aspx

表分区有何帮助?

通过分区提高性能

考虑到理想的查询是按设备和日期时间过滤,问题是:

  1. 您认为第一个数据库设计(带分区)的最有效和最理想的查询是什么?
  2. 您真的认为针对第一个数据库设计的最有效查询比第二个(我上面写的那个)更好吗?
  3. 如果前一个是肯定的,您真的认为有两个额外字段(Id 和 Date-Id)和一个额外索引的改进值得吗?

非常感谢!!

Mik*_*Fal 11

如果分区方案是为您的特定查询服务而构建的,那么使用分区只会帮助您提高查询性能。

您将不得不查看您的查询模式并查看它们如何访问表,以便确定最佳方法。这样做的原因是您只能在单个列(分区键)上进行分区,这将用于分区消除

有两个因素会影响分区消除是否可以发生以及它的执行情况:

  1. 分区键- 分区只能发生在单个列上,并且您的查询必须包含该列。例如,如果您的表按日期分区并且您的查询使用该日期列,则应该发生分区消除。但是,如果查询谓词中不包含分区键,则引擎无法执行消除。
  2. 粒度- 如果您的分区太大,您将不会从消除中获得任何好处,因为它仍然会拉回比它需要的更多的数据。但是,让它变小,变得难以管理。

在许多方面,分区就像使用任何其他索引一样,还有一些额外的好处。但是,除非您处理非常大的表,否则您不会意识到这些好处。就个人而言,我什至不考虑分区,直到我的表大小超过 250 GB。大多数情况下,定义良好的索引将涵盖小于该值的表上的许多用例。根据您的描述,您没有看到巨大的数据增长,因此正确的索引表可能对您的表执行得很好。

我强烈建议您检查是否确实需要分区来解决您的问题。人们通常会出于以下目的对一个非常大的表进行分区:

  • 在不同类型的磁盘之间分配数据,以便将更多“活动”数据放置在更快、更昂贵的存储上,而将活动较少的数据放置在更便宜、更慢的存储上。这主要是一种节省成本的措施。
  • 协助超大表的索引维护。由于您可以单独重建分区,这有助于以最小的影响正确维护索引。
  • 利用分区来改进归档过程。请参阅滑动窗口