EF Core 6与SSMS统计SQL执行时间差异超10倍的原因咨询
EF Core与SSMS执行时间差异超10倍的核心原因
以下是导致两者耗时差距的几个关键因素:
执行计划缓存与复用差异
EF Core默认采用参数化查询,首次执行后SQL Server会将生成的执行计划存入缓存,后续请求直接复用,省去了重复编译的开销。如果是把EF Core生成的SQL直接复制到SSMS以硬编码参数的形式执行,或者SSMS的会话环境与EF Core不一致,服务器会判定这是全新查询,每次都要重新编译执行计划——复杂查询的编译时间往往远超过执行本身,直接拉高了总耗时。会话SET选项不一致导致执行计划无法共享
SQL Server的执行计划缓存依赖于完整的会话SET选项集合,以下选项的差异会导致计划无法复用:ARITHABORT:SSMS默认开启,EF Core默认关闭- 其他如
ANSI_NULLS、QUOTED_IDENTIFIER(虽通常两者都设为ON,但需确认是否有自定义修改)
当EF Core与SSMS的SET选项不匹配时,服务器会为双方的查询生成独立执行计划,SSMS的查询因无缓存计划可复用,每次都要重新编译,耗时剧增。
参数嗅探与参数值差异
SQL Server的参数嗅探机制会根据首次执行的参数值生成优化执行计划。如果EF Core使用的参数值和你在SSMS测试时用的参数值筛选性差异大(比如EF Core传的参数返回少量数据,SSMS用的参数返回大量数据),后者的执行计划会因处理更多数据而耗时更长。计时范围的本质差异
EF Core日志中Microsoft.EntityFrameworkCore.Database.Command的Elapsed时间,是客户端从发送命令到接收完所有结果的总耗时(含网络往返);而SSMS的set statistics time统计的是服务器端的全流程执行时间(含查询编译、执行、数据准备)。但你的场景中EF Core耗时远低于SSMS,核心原因还是前面的执行计划缓存或SET选项问题。
验证方法
- 在SSMS中执行EF Core生成的参数化查询(而非硬编码参数的SQL),先执行EF Core默认的SET命令对齐环境:
再开启SET ANSI_NULLS ON; SET ANSI_PADDING ON; SET ANSI_WARNINGS ON; SET CONCAT_NULL_YIELDS_NULL ON; SET QUOTED_IDENTIFIER ON; SET ARITHABORT OFF;set statistics time on执行查询,对比耗时是否接近EF Core的结果。 - 用
sys.dm_exec_query_stats查看执行计划缓存,确认EF Core的查询是否复用了计划,而SSMS的查询是否每次都触发重新编译。
内容的提问来源于stack exchange,提问作者AnotherAcronym
相关产品推荐
相关产品推荐

