我对幽灵清理过程的理解是,每五秒钟它会查看索引中已删除的幽灵记录。因此它不会使系统超载,它每次只会“清理”大约十页。
那么,这意味着它每五秒钟只能清理大约 80k 条记录?似乎我的索引总是充满虚影记录,清理永远也完成不了。
因此,假设我运行删除操作,大概有一百万行,而这数百万行的索引记录大小大约为 8Gb。因此大约是 80k 差值的 100,000 倍。这是否意味着幽灵清理过程将花费 500,000 秒或将近六天才能完成?
显然我在这里遗漏了一些东西,因为清除幻影记录需要那么长时间,这没有道理。那么命中同一索引的其他活动呢?幻影清理过程是否会导致等待,还是必须等待其他过程?
[这个问题是由我们在 OpsMgrDW 中看到的性能问题引起的,我们想了解有关此过程的更多信息]
答案1
我写了两篇全面的博客文章来解释鬼影清理(这是唯一对其进行深入解释的地方,无论是印刷版还是在线版)。
第一个是存储引擎内部:深度清理幽灵第二个是幽灵清理重现是的,每次 10 页,并且幽灵清理任务可能永远无法赶上大量的连续删除。
除了每 5 秒 10 页的清理之外,还可以通过确保存储引擎“看到”幽灵记录来积极触发幽灵清理。使用类似以下方法强制扫描受影响的表或索引
从 [问题表] 中选择 * (索引 = 问题索引)
这将排队请求以积极清除幽灵记录。但请注意,在执行此操作时,它将生成大量事务日志。它们还应通过索引重建或重组作为常规索引维护的一部分来清除。
希望这可以帮助。
答案2
我一直认为索引重建会在结构发生改变时“修复”所有剩余的问题。
答案3
几年前,我遇到了这个问题,但无法通过配置、触发幽灵清理或任何类似操作来修复它。我当时使用的数据库不断插入和删除,由于幽灵清理触发,SQLServer 会定期锁定。
我最终的解决方案是按时间对问题表进行分区,而不是删除旧行,而是直接删除旧表。这非常有帮助。这可能不适合你的情况,但它适用于许多情况,只是有些不同。
答案4
我们也有类似的情况。我们的一个表有很多幽灵记录,而这些记录没有被幽灵清理过程清理掉。DB Shrinking、DBCC Cleantable、重建索引和重新组织索引都没有用。为了解决这个问题,我们将数据传输到临时表,然后截断表并将数据传输回截断表。该表包含 LOB 数据(2 个 nvarchar(max) 列)。还有其他方法可以解决这个问题吗?