使用Dapper的QueryMultiple时是否会重复执行所有SQL查询?
Dapper QueryMultiple 执行逻辑说明
核心结论
QueryMultiple 不会重复执行传入的SQL语句,你观测到的两条相同查询记录是SQL Server系统视图的统计特性导致的假象,并非实际执行了两次。
底层运行逻辑
- Dapper的
QueryMultipleAsync/QueryMultiple方法会将你传入的多段用分号拼接的SQL作为单个批处理命令,一次性发送到SQL Server执行,全程仅和数据库发生一次网络往返。 - SQL Server执行该批处理后会返回多个结果集,Dapper会将结果集缓存在本地内存中,你后续调用
Read<T>()方法只是从本地缓存中读取对应结果集,不会再向数据库发送任何请求。
观测到重复记录的原因
你使用的查询语句基于sys.dm_exec_query_stats系统视图,该视图是执行计划统计视图,出现两条相同记录的常见原因有两个:
- Dapper默认会用
sp_executesql执行SQL语句,该视图会同时统计sp_executesql的外层调用记录、以及内层实际执行的SQL语句记录,两条记录的SQL文本完全相同、执行时间一致,本质是同一次执行的两个统计条目。 - 包含多语句的批处理在执行时,系统视图会同时统计整个批处理的执行记录、以及每个独立语句的执行记录,也会出现多条内容重叠的统计项。
验证方法
你可以用SQL Server自带的**扩展事件(Extended Events)**或者SQL Server Profiler抓实际执行请求事件,只会抓到1次你拼接的完整SQL执行记录,不会出现重复执行的情况。
注意:你预期看到两条独立的
select语句记录也是不符合实际运行逻辑的,你是将两段SQL拼接为一个字符串传入的,Dapper不会主动拆分SQL,数据库收到的就是完整的带分号的批处理语句,所以正常的执行记录只会显示完整的拼接SQL。
性能影响说明
QueryMultiple是Dapper专门为了减少数据库往返次数设计的功能,相比分两次执行两个查询,网络IO开销更低,不存在额外的性能损耗,你可以正常使用。
内容的提问来源于stack exchange,提问作者wamaral
相关产品推荐
相关产品推荐

