为何我的内存优化表变量占用磁盘空间?
我刚看到你的问题,这确实是个容易让人困惑的点——毕竟“内存优化”四个字很容易让人觉得它完全活在内存里,跟磁盘没什么关系。但在SQL Server里,这类表变量确实会占用一定的磁盘空间,主要是这几个原因:
检查点与恢复机制的需要
内存优化表的核心数据虽然常驻内存,但SQL Server会定期生成检查点(checkpoint),把内存中的数据快照写入数据库的MEMORY_OPTIMIZED_DATA文件组。这么做是为了在数据库重启或者发生故障时,不用完全靠重放事务日志来恢复数据,能大幅加快恢复速度。同时,所有对这个表变量的操作(比如你执行的INSERT和后续查询)都会被记录到事务日志中,日志文件本身就是磁盘上的文件,自然会占用磁盘空间。系统元数据的存储
你创建的tblLocation_InMem这个表类型,它的定义信息(比如列结构、索引配置)会被存储在数据库的系统目录里。这些元数据是保存在磁盘上的(要么在用户数据库,要么在master系统库),虽然这部分占用的空间很小,但也是磁盘占用的一部分。内存压力下的数据溢出
即使内存优化表变量默认采用SCHEMA_ONLY的持久化模式(也就是重启后数据会丢失),当表变量里的数据量过大,或者服务器内存资源紧张时,SQL Server可能会把部分数据溢出(spill)到tempdb的磁盘文件中,以此来缓解内存压力。你的场景是用它存储复杂查询的中间结果,还多次访问,如果数据量不小的话,就有可能触发这种情况。
要说明的是,这些磁盘占用是SQL Server为了保证可靠性、内存管理平衡所做的设计,内存优化表变量的性能优势(比如锁和闩锁的减少、更快的查询响应)依然存在,磁盘占用只是它运行机制的一部分而已。
内容的提问来源于stack exchange,提问作者Ian

