【问题标题】:SQL Server Fragmentation ProblemsSQL Server 碎片问题
【发布时间】:2013-11-15 10:06:43
【问题描述】:

我的数据库中有几个表(用户和用户记录)变得非常碎片化(如 99%)并导致整个数据库和网站停止运行。

UserRecord 有点像该用户在某个时间点的快照。用户就像该用户的主记录。用户有 0 到多个 UserRecords。 User 有大约 100 万行,UserRecord 有大约 250 万行。这些表被写入很多。他们也被大量搜索。他们都会变得更大。严重碎片化的主要索引是 User 和 UserRecord 表的主键。

数据库是 SQL Server 2012,我使用的是实体框架,我没有使用任何存储过程。

表格看起来像这样:

USER
UserName string PK ClusteredIndex
FirstName string
LastName string
+SeveralMoreRows

USER_RECORD
UserRecordId int PK ClusteredIndex
ListId int FK(List)
UserName string FK(User) NonClusteredIndex
Community string NonClusteredIndex
DateCreated datetime
+LotsMoreRows

LIST 
ListId int PK & ClusteredIndex
Name string
DateCreated datetime

(不确定 List 这是否重要,但我认为我会包含它,因为它与 User_Record 相关。List 有 0 到多个 UserRecord)

我们设置了一个 SQL 维护计划来每天重建索引,这确实有帮助,但有时还不够。

一位朋友建议我们使用两个数据库,一个用于读取,一个用于写入,我们将读取 DB 与写入 DB 同步。并不是说我对此一无所知,但我看到这个解决方案的第一个问题是我们在查看网站时需要最新数据。例如,如果我们更新用户详细信息或用户记录,我们希望立即看到这些更改。

有人对我如何在问题失控之前解决这个问题有任何建议吗?

【问题讨论】:

  • 表定义是什么?您是否使用 GUID 作为主键?
  • 您是否在 uniqueidentifier 列上建立了聚集索引?这通常会在一些插入后导致碎片......因为这些值是随机的......
  • 我在问题中添加了更多细节
  • 您是如何得出碎片化导致问题的结论的?绝大多数查询不会针对特定用户进行搜索吗?
  • 站点损坏,大多数查询超时,我们查看索引的碎片,它们高达 99%,我们运行 SQL Server 索引重建/修复任务,一切正常又好了。

标签: sql-server database database-design sql-server-2012 database-fragmentation


【解决方案1】:

聚集索引控制磁盘上数据的顺序。这是通常建议您设置一个始终递增的整数键作为聚集索引的主要原因之一。这样,随着更多数据添加到表中,它们将添加到当前现有数据的末尾。

如果它不是一个自动递增的数字并且新行可能包含在现有值之间排序的值,那么 SQL Server 基本上会将数据推送到它所属的磁盘上(以保留聚集索引键值的顺序) ,产生碎片和潜在的严重开销,因为 IO 写入进一步减慢了数据库。

我怀疑您的 UserRecord 值存在同样的问题。

所以我要做的是为每个表添加一个单独的集群自动递增主键,并在必要时重新处理您的 FK 引用和查询。

【讨论】:

  • 为什么不将 PK 索引声明为非聚集的?
  • 通常最好在表上有一个聚集索引。即使您忽略它并创建一个非集群 PK,它也会将该表存储为一个具有许多其他问题的 HEAP。例如,针对它运行的所有查询首先必须找到非聚集索引匹配,然后从 HEAP 中找到匹配的行以获取其他值,因为它们不像聚集索引那样容易获得。同样,产生不必要的开销会减慢 DB。 Google 有几篇关于 HEAP 与 CLUSTERED 表的好文章。
  • 谢谢,听起来 SQL Server 在索引方面与其他 DBMS(例如 Postgres、Oracle)截然不同。
  • 增加填充因子并结合每日索引重建是否可以替代在 User 表上添加自动递增 int 主键?
  • 是的,你可以这样做欧文,但不断增加的集群价值通常是一个好主意。如果您有日期列,则可以在该列而不是主键上进行聚类。您可以使用维护任务或自定义作业在 SQL Server 中运行索引重组或每晚重建。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多