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

时间:2016-10-21 06:02:33

标签: sql sql-server memory-management memory-leaks

我有一个大的游标库查询,它在作业下的存储过程中运行。它整天在一个循环中对大量市场数据进行大量计算。每个这样的迭代都会从磁盘中汇集历史时间序列,将其填充到具有适当索引的临时表中,将它们连接到具有中间结果的多个结构中,并将计算输出存储到磁盘。在每个循环结束时,我(主要)删除或截断所有临时表以释放tempdb内的用户对象页面,并为下一次迭代准备名称空间。

我的问题是,在每个周期之后,所有内部对象,DB Engine为查询执行而创建并将它们转储到tempdb, - 保留为它们保留的磁盘空间,甚至在事务提交后解除分配。随着下一批新的内部对象被刷到磁盘,它会累积到每个周期。

它导致永久的tempdb集合,所有累积的保留空间都与新的和新的解除分配的内部对象相关。数据库引擎仅在会话结束后,当proc完成它的循环时,释放/缩小(无论如何)这些浪费的磁盘空间。

我可以通过减少每个作业运行的周期数来解决问题,然后重新启动它。但我想要一个完整的基本决定:我需要在会话中使用命令或任何类型的技巧来强制垃圾收集,以完全清理/终止已释放的内部对象并释放为它们保留的tempdb磁盘空间。几天的谷歌搜索没有帮助。伙计们,帮忙!

1 个答案:

答案 0 :(得分:1)

我们有完全相同的问题:

  1. 每晚都会执行耗时的重新计算;
  2. 使用了很多临时表来使用并行 执行计划
  3. 为了解决这个问题,我们只是将流程划分为在单独会话中执行每个流程的小流程,但是链接(为了避免阻塞问题) - 当第一部分执行时,它会激活下一部分,然后在执行之后,它会触发下一部分。

    例如(如果你有办法链接计算),你可以打破循环迭代,用不同的参数分隔调用过程。在不同的会话中执行,当每个会话结束时,页面将被释放。