Linq to SQL 查询仅返回所需最大值的实现与性能优化咨询
结论
只要你所用仓储的Get()方法返回的是IQueryable<Template>而非已经执行求值的IEnumerable<Template>,更新后的写法完全可以实现仅查询所需字段、避免拉取全量数据的优化效果。
原有写法的问题
旧代码里在做完过滤和排序后立刻调用了ToList(),这一步会直接触发SQL执行,把满足条件的所有Templates表记录的全字段数据全部拉到服务端内存中,后续的投影取Modified字段、排序取最大值都是内存操作,数据量大的时候会造成极大的内存、带宽浪费,性能很差。
新写法的优化逻辑
你调整后的写法会把过滤条件、取最大值的操作全部通过表达式树传递给LINQ to SQL提供器,最终会被翻译成类似下面的SQL在数据库端执行:
SELECT MAX([Modified]) FROM [dbo].[Templates] WHERE [IsCurrentVersion] = 1 AND [Status] = @PublishedStatusValue
数据库直接计算出最大值后仅返回单个DateTime类型的结果,不会拉取任何行数据,也不会查询其他无关字段,完全符合你的优化需求。
验证建议
如果要确认效果,可以开启SQL执行日志打印,或者用SQL Profiler抓取实际执行的SQL语句,确认是否生成了上述的MAX查询即可。唯一需要注意的是如果你的仓储Get()方法内部做了ToList()之类的立即求值操作返回IEnumerable,那依然会拉取全量,但从你原有代码Get()后可以直接接Where的写法来看,基本可以确定返回的是IQueryable,不会有这个问题。
内容的提问来源于stack exchange,提问作者Jefferson
相关产品推荐
相关产品推荐

