在SQL Server中快速分段索引

时间:2014-04-17 09:45:46

标签: sql sql-server sql-server-2008

我有一个查询,目前在两台物理服务器上运行,大约7秒就可以了。查询相对复杂,因为它连接了几个表并由实体框架构成。我目前正在将数据库迁移到虚拟托管环境,除了这一个查询之外,一切似乎都没问题。查询虚拟托管的SQL Server实例时,查询最初会在7秒内运行,但一两个小时后会突然大约需要8分钟。

在慢速状态下查看执行计划时,我发现了意外的全表扫描。如果我重建该表上的索引,它会立即恢复为7秒。但是,在一个小时左右的时间内,它将转为8分钟。

有问题的表几乎没有变化,而且我经常能够确定它运行良好和运行缓慢之间的零变化。重建索引后,碎片下降到0.02%左右,但在一两个小时内,它会跳到50%-60%之间。

  • 页面丰满度 - 52.95%
  • 总碎片数 - 54.19%
  • 平均行数 - 338
  • 深度 - 3
  • 转发记录 - 0
  • 幽灵记录 - 0
  • 索引类型 - CLUSTERED INDEX
  • 叶级行 - 134900
  • 最大行数 - 604
  • 最小行数 - 239
  • Pages - 10736
  • 分区ID - 1
  • 版本鬼行 - 0

我不确定碎片是否会导致这个问题,但我完全不知道为什么它可能会如此迅速地碎片化。谁能解释一下?

2 个答案:

答案 0 :(得分:2)

  • 您可以看到many fragmentation techniques的差异,看看哪种情况最适合您的情况。

  • FILL FACTOR也会影响碎片化。

  • 该表上的统计数据可能未更新

  • 您可能是参数嗅探问题的受害者(查询计划已缓存但不是最佳)。你能检查same query plan是否用于两种情况吗?

  • 您确定两个查询都相同吗?如果没有,有什么区别?

如果您在查询运行良好时将sys.dm_db_index_physical_stats的碎片信息放在打印屏幕上,我们可能会给您提供更多帮助。

稍后编辑: 使用默认填充因子,当页面拆分发生时,一半行保留在初始页面中,另一半将移动到新页面。

你几乎没有什么变化,但是肯定会有两倍的页数,所以我怀疑由于53%的内部碎片而对表中的所有(或几乎所有)行进行了“小更新”。

要执行的其他行动:

  • 1 /发布你的表格结构会很有用,看看。
  • 2 /您是否有任何具有CHAR数据类型的列?
  • 3 /列出页面中的平均行数(快速与慢速)
  • 4 /检查触摸该表的所有存储过程/查询
  • 5 /添加触发器并记录(在另一个表中?)在您的表上执行的操作(您可能有UPDATE TableX SET colA = colA WHERE 1=1

让我们发布。

答案 1 :(得分:0)

据我所知,索引碎片也可能导致性能下降。可能因为DML到该表而发生。

您看到页面丰满度约为52%。你有10736个带有聚簇索引的页面,想象一下当用完全索引扫描执行选择查询时,它将遍历页面直到它获得匹配记录。它会让你失去性能。

可能会发生碎片,并且使用表维护来重建索引是正常的。但我认为在一小时内碎片达到30%以上是好的。我不确定它是如何发生的,因为你没有提供详细信息。

也许您可以做的是:

  1. 检查此表中的索引。
  2. 查询触摸表格
  3. 等待你的反馈..