SQL Server:强制清理tempdb中已释放的内部对象,以释放在打开的会话中为它们保留的磁盘空间



我有一个大型游标基查询,它在作业下的存储过程中运行。它整天在循环中为一堆市场数据进行大量计算。每次这样的迭代都将磁盘上的历史时间序列片段池化,用适当的索引将其捕获到临时表中,将它们连接到具有中间结果的许多转换中,并将计算输出存储到磁盘。在每个循环结束时,我删除(大部分)或截断所有临时表,以释放tempdb中用户对象的页面,并为下一次迭代准备名称空间。

我的问题是,在每个周期之后,DB引擎为查询执行创建的所有内部对象并将它们转储到tempdb,即使在事务提交后被释放,也要为它们保留磁盘空间。在每个循环中,当下一批新的内部对象被刷到磁盘上时,它会加起来。

它导致永久的tempdb增长,所有与新的和新的内部对象释放相关的保留空间都在累积。DB引擎释放/收缩(无论如何)这些浪费的磁盘空间只有在会话关闭时,当进程完成它的周期。

我可以通过减少每个作业运行的周期数来克服这个问题,只需重新启动它。但是我想要一个完整的基本决策:我需要一个命令或任何类型的技巧在会话中强制垃圾收集,以根据我的需求完全清理/杀死已释放的内部对象,并释放为它们保留的tempdb磁盘空间。几天的谷歌搜索也无济于事。各位,帮帮忙!

我们有完全相同的问题:

  1. 每天晚上执行耗时的重新计算;
  2. 为了使用并行,使用了很多临时表执行计划

为了解决这个问题,我们将进程划分为小进程,每个进程在单独的会话中执行,但是链接(为了避免阻塞问题)-当第一部分执行时,它会触发下一部分,然后在执行后,它会触发下一部分。

例如(如果你有链式计算的方法),你可以中断你的循环迭代,用不同的参数分开调用过程。在不同的会话中执行,当每个会话完成时,页面将被释放。

最新更新