普通表变量不支持加速,因其无索引、无统计信息、不参与优化器估算;提速须改用内存优化表变量(需先CREATE TYPE、仅限本机编译存储过程、DURABILITY=SCHEMA_ONLY)或替换为其他机制。

SQL Server 2019 中的普通表变量(@table)本身不支持“配置加速”,它没有索引、不走统计信息、不参与查询优化器的代价估算——你写 INSERT INTO @t,本质上就是单行缓冲写入,性能上限很低。真要提速,得换路子:要么用内存优化表变量(但限制极多),要么绕开表变量改用其他机制。
为什么普通表变量 INSERT 不可配、也不该配
普通表变量是编译时静态结构、运行时纯内存对象,SQL Server 不为它生成执行计划缓存中的独立计划分支,也不维护统计信息。这意味着:
-
INSERT INTO @t SELECT ...的执行路径完全取决于右侧查询,@t 本身不贡献任何优化点 - 无法在表变量上建索引(除主键/唯一约束隐式创建的堆外),
WHERE或JOIN时全表扫描不可避免 - 插入大量数据(比如 >1000 行)时,性能会断崖式下降,且无法并行
别试图给 DECLARE @t TABLE(...) 加 hint、加选项或调兼容级别——语法根本不允许,也无实际效果。
想快?必须用内存优化表变量,但得满足全部硬条件
只有 CREATE TYPE ... WITH (MEMORY_OPTIMIZED = ON) 定义的类型,配合本机编译存储过程,才能兑现“快速 INSERT”。漏掉任一条件,就退回普通表变量行为,甚至更慢。
- 必须先
CREATE TYPE dbo.tvp_fast AS TABLE (...) WITH (MEMORY_OPTIMIZED = ON, DURABILITY = SCHEMA_ONLY),不能DECLARE @t TABLE (...) WITH (MEMORY_OPTIMIZED = ON)(语法报错Incorrect syntax near 'AS TABLE') - 只能在
CREATE PROCEDURE ... WITH NATIVE_COMPILATION, SCHEMABINDING中使用,普通 T-SQL 批处理里声明DECLARE @t dbo.tvp_fast无效 -
DURABILITY = SCHEMA_ONLY是唯一合理选项;若误设为SCHEMA_AND_DATA,每次 INSERT 都写日志、触发 GC,比临时表还慢 - 哈希索引的
bucket_count必须预估——比如预期插 5000 行唯一键,设成 8000~10000;填1000000会浪费数 MB 内存,且无性能增益
替代方案往往比“配表变量”更现实
绝大多数场景下,与其折腾内存优化表变量的部署和限制,不如直接换载体:
- 数据量
- 数据量 100–10000 行 → 改用本地临时表
#t,可建索引、有统计信息、能被优化器重用,INSERT INTO #t SELECT ...比表变量快 3–5 倍 - 需要高频读写 + 并发安全 → 用
##global_temp或持久内存优化表(DURABILITY = SCHEMA_AND_DATA),但得配好内存池,且重启后数据还在 - 纯中间计算、无 JOIN/WHERE → 考虑 CTE 或窗口函数直接流转,避免落表
真正卡在 INSERT 性能上的,往往不是表变量本身,而是没意识到:它天生不是为批量写设计的。强行让它快,等于给自行车装涡轮——结构不支撑。

















