【发布时间】:2018-07-09 21:10:39
【问题描述】:
我有一个包含 3 个内部连接表的数据集,其中包含来自 MySQL 数据库的大约 18,000 条记录。我的函数应该是获取所有相关数据,然后通过用户提供的一些参数对其进行过滤,然后返回过滤器适用的项目数。
当我使用标准数据读取器时,这确实可以正常工作,但是我刚刚将应用程序转移到使用实体框架来尝试提高性能,为此我正在使用 LazyLoadingProxies - 我认为这与问题有关.
我的功能的主要部分是
- 获取所有数据项
- (对于每个参数)复制所有数据项
- 获取过滤项的计数
代码如下所示
var EventsLogged = context.EventLogs.Where(x => x.Event.GameId == request.GameId
&& (!request.EventId.HasValue || x.EventId == request.EventId.Value)
&& (!request.StartTime.HasValue || x.Created >= request.StartTime.Value)
&& (!request.EndTime.HasValue || x.Created <= request.EndTime.Value));
if (EventsLogged.Count() <= 0)
{
response.AddErorrMessage("No data found for Event.");
}
else
{
//Some other stuff happens here not related to do with working on the parameters
IEnumerable<EventLogs> filteredEvents = EventsLogged;
filteredEvents = FilterResultsSet(filteredEvents, parametervalue);
return filteredEvents.Select(x => x.UserId).Distinct().Count();
}
该函数工作正常,过滤也很好,然后当我们点击 Select.Distinct().Count() 时,处理时间会飙升到一个疯狂的数量 - 我等了大约 20 分钟才放弃。
在我的输出窗口中,我可以看到正在输出的 SQL 部分,就好像此时实际上正在执行查询一样,但一次只有 1 条记录。
从我已经看过的内容来看,关于获取 IEnumerable 的计数有一些规则,并且要获得计数必须对其进行计数。
由于我不关心此查询中的任何内容,只关心计数,有什么方法可以实现这一点 - 还是我需要重新考虑我的整个策略。
【问题讨论】:
-
FilterResultsSet()看起来像什么?它是否返回IQueryable<>?如果是这样,并且如果看起来很快,可能是这样,直到你真正做到了.Select(),你并没有具体化记录,而且你在FilterResultsSet()中所做的任何事情都可能效率低下 -
NULLable列 和针对此类的测试优化不佳。
标签: mysql performance linq .net-core entity-framework-6