LinqPad 和实践中两个 Linq 查询之间的性能问题
我有一个查询:
(from sr in ctx.STARS_Route
where sr.STARS_RouteStopDestination.Any(i => i.IsWorkingSet == true && i.STARS_DistrictRoute.DistrictId == districtId) == true
select sr.DistrictRouteNumber).Distinct();
在 LinqPad 中,查询运行时间约为 0.3 秒。 STARS_RouteStopDestination 表中大约有 800K 条记录,但平均返回约为 30-90 条记录。
实际上,从该查询返回结果的方法花费了 4 秒多的时间!这没有任何意义。
我唯一能想到的是 .Any 子句花费了很多时间,但 LinqPad 说查询速度很快。我设置了一个测试(请原谅这些名字):
using (STARSEntities ctx = new STARSEntities())
{
var Original = (from sr in ctx.STARS_Route
where sr.STARS_RouteStopDestination.Any(i => i.IsWorkingSet == true && i.STARS_DistrictRoute.DistrictId == districtId) == true
select sr.DistrictRouteNumber).Distinct();
var Entity = (from rsd in ctx.STARS_RouteStopDestination
where rsd.STARS_DistrictRoute.DistrictId == districtId
&& rsd.IsWorkingSet == true
select rsd.STARS_Route.DistrictRouteNumber).Distinct();
DateTime startOriginal = DateTime.Now;
routes = Original.ToList();
Debug.WriteLine("Original took: " + (DateTime.Now - startOriginal).ToString());
DateTime startEtity = DateTime.Now;
routes = Entity.ToList();
Debug.WriteLine("Entity took: " + (DateTime.Now - startEtity).ToString());
}
输出让我大吃一惊:
原始拍摄时间:00:00:04.0270000
Entity take: 00:00:00.0200000
为什么使用 .Any 子句的查询运行时间要长得多,为什么 LinqPad 会说原始查询比针对同一数据集的实体查询运行得稍快?
I have a query:
(from sr in ctx.STARS_Route
where sr.STARS_RouteStopDestination.Any(i => i.IsWorkingSet == true && i.STARS_DistrictRoute.DistrictId == districtId) == true
select sr.DistrictRouteNumber).Distinct();
In LinqPad the query was running at roughly 0.3 seconds. There are roughly 800K records in the STARS_RouteStopDestination table, but the average return is about 30-90 records.
In practice, the method returning the results from this query was taking 4+ seconds! It didn't make any sense.
The only thing I could think of is that the .Any clause was taking a lot of time, but LinqPad said the query was fast. I set up a test (please forgive the names):
using (STARSEntities ctx = new STARSEntities())
{
var Original = (from sr in ctx.STARS_Route
where sr.STARS_RouteStopDestination.Any(i => i.IsWorkingSet == true && i.STARS_DistrictRoute.DistrictId == districtId) == true
select sr.DistrictRouteNumber).Distinct();
var Entity = (from rsd in ctx.STARS_RouteStopDestination
where rsd.STARS_DistrictRoute.DistrictId == districtId
&& rsd.IsWorkingSet == true
select rsd.STARS_Route.DistrictRouteNumber).Distinct();
DateTime startOriginal = DateTime.Now;
routes = Original.ToList();
Debug.WriteLine("Original took: " + (DateTime.Now - startOriginal).ToString());
DateTime startEtity = DateTime.Now;
routes = Entity.ToList();
Debug.WriteLine("Entity took: " + (DateTime.Now - startEtity).ToString());
}
The output blew my mind:
Original took: 00:00:04.0270000
Entity took: 00:00:00.0200000
Why does the query with the .Any clause take so much longer to run, and why would LinqPad say that the Original query runs slightly faster than the Entity query against the same dataset?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您只是对两个不同的对象进行操作,这两个对象有两种不同的策略来获取结果。 LINQPad 生成 LINQ to SQL 模型,并将代码注入到范围内具有此模型的方法中。
您的 STARSEntities 类属于不同类型,并且可能与数据库具有完全不同的交互。
LINQPad 有自己的视图,显示正在运行的 SQL。您应该将其与 EF 模型执行的 SQL 进行比较。当您执行时,这会显示在 SQL Server Profiler 中。
You are simply acting upon two different objects that has two different strategies of obtaining the result. LINQPad generates a LINQ to SQL model and injects your code into a method with this model in scope.
Your STARSEntities class is of a different type and probably has a completely different interaction with the database.
LINQPad has its own view that displays the SQL being run. You should compare it to the SQL being executed by the EF model. This is displayed in the SQL Server Profiler when you execute.