大内存环境中的 SQL Server TempDB 行为

Han*_*non 12 performance sql-server-2005 sql-server tempdb

读完这个问题让我想起了我不久前的一个问题。

我们有一个具有 512GB RAM 的 SQL Server,主数据库是 450GB。我们在 TempDB 中看到了很多动作(好吧,我认为这是“相当多的动作”——可能不是!)。我安装了 RamDisk Plus Server 的演示版,创建了一个 50GB 的 ramdrive,将 TempDB 指向它,但并没有看到性能有任何改善。

写入 TempDB 是否总是导致对磁盘的实际物理写入,或者 TempDB 写入是否由 SQL Server 缓存以便像在 Windows 文件系统缓存中那样延迟写入?

在这种情况下,ramdisk 毫无意义吗?

我知道 SQL Server 6.5 支持 TempDB-In-Ram,但我看到它很久以前就停产了!

Mar*_*ith 20

写入 TempDB 是否总是导致对磁盘的实际物理写入,或者 TempDB 写入是否由 SQL Server 缓存以便像在 Windows 文件系统缓存中那样延迟写入?

他们总是吗?绝对不是。他们曾经吗?是的,但不是典型机制的结果。这里的参考是检查点对 tempdb什么作用?.

在“行为良好”的系统中,写入用户数据库文件发生在检查点上。在行为不佳的系统中,当惰性写入器需要从缓冲池中刷新页面以为其他页面腾出空间时,也会发生写入。

仅当 tempdb 日志文件已满 70% 时才对 tempdb 执行检查点 - 这是为了尽可能防止 tempdb 日志增长(请注意,长时间运行的事务仍然可以实质上保留日志人质并阻止其清除,就像在用户数据库中一样)。

但是没有必要将 tempdb 刷新到磁盘,因为崩溃恢复永远不会在 tempdb 上运行,它总是在启动时重新创建。

发生崩溃时 Tempdb 不会恢复,因此无需将脏的 tempdb 页面强制写入磁盘,除非惰性写入器进程(缓冲池的一部分)必须为来自其他数据库的页面腾出空间。

这很显着(这让我感到惊讶)是将 tempdb 页面写入磁盘的唯一机制。如果存在缓冲池压力,tempdb 页面可能会刷新到磁盘。如果没有,就不应该发生。

编辑:对于在检查点之外写入页面的用户数据库来说,“行为不当”是否是适当的描述是有争议的。不寻常的、非典型的,或者只是不理想?

附加编辑(以下评论/与@PaulWhite 聊天):

上面明显的遗漏是临时表不是 tempdb 流量的唯一来源。引用理解散列、排序和交换溢出事件

通过使用(有点)大量内存作为中间存储,某些 SQL Server 查询执行操作被校准为最佳执行。查询优化器将使用此内存暂存器根据这些运算符选择一个计划并估算成本。但这当然只是一个估计。在执行时,估计可能被证明是错误的,即使没有足够的内存,计划也必须继续。在这种情况下,这些操作符会溢出到磁盘。

我错误地假设溢出操作的物理写入背后的机制与前面描述的完全相同,即由于缓冲池的压力(由溢出引起)懒惰写入器强制 tempdb 页面到磁盘。

@PaulWhite 解释了我错在哪里(感谢 Paul!):

我想您是在问为什么当查询超过其工作区内存授权时会发生物理 tempdb 活动,而不是仅使用 tempdb-in-memory 如果这样做,则查询将使用比其授权更多的内存,从而破坏了限制内存的意义补助金放在首位。

溢出在写入到存储方面确实很特别。物理 tempdb 活动在溢出时可见,即使面对大量空闲内存和 tempdb 上的零压力也是如此。

Paul 还向我指出了他的博客文章高级 TSQL 调优:为什么内部知识很重要,其中包括用于演示溢出的示例脚本,供那些想要深入研究的人使用。