我的数据库中有几个表(User& UserRecord)变得极其分散(如99%)并导致整个数据库,因此网站陷入停顿。
UserRecord有点像该用户在某个时间点的快照。用户就像该用户的主记录。用户有0到多个UserRecords。用户有大约一百万行,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有关。列表有0到多个UserRecords)
我们已经设置了一个SQL维护计划来每天重建索引,这确实有帮助,但有时还不够。
一位朋友建议我们使用两个数据库,一个用于读取,一个用于写入,我们从写入DB同步读取DB。并不是说我对此有所了解,但我在解决这个问题时遇到的第一个问题是我们在查看网站时需要最新的数据。例如,如果我们更新用户详细信息或UserRecord,我们希望立即看到这些更改。
有没有人对如何在失控之前解决这个问题有任何建议?
答案 0 :(得分:5)
聚簇索引控制DISK上数据的顺序。这是为什么通常建议您设置一个始终增加的整数键作为聚簇索引的主要原因之一。这样,随着更多数据添加到表中,它们被添加到当前现有数据的末尾。
如果它不是自动增加的数字,并且新行可能包含将在现有值之间的某个位置排序的值,则SQL Server将基本将数据推送到它所属的磁盘上(以保留聚簇索引键值的顺序)由于IO写入进一步减慢了数据库的速度,因此产生碎片并可能造成严重的开销。
我怀疑您的UserRecord值存在同样的问题。
所以我要做的是为每个表添加一个单独的集群自动增加主键,并重新编写你的FK引用和放大器。必要时查询。