实体框架 DbContext 筛选的计数查询使用变量非常慢



使用 ADO.NET 实体数据模型,我针对包含 1800 条记录的表构建了下面的两个查询,该表包含 30 多个字段,可产生惊人的结果。

// Executes slowly, over 6000 ms
int count = context.viewCustomers.AsNoTracking()
.Where(c => c.Cust_ID == _custID).Count();
// Executes instantly, under 20 ms
int count = context.viewCustomers.AsNoTracking()
.Where(c => c.Cust_ID == 625).Count();

我从数据库日志中看到实体框架提供的查询几乎相同,只是过滤器部分使用参数。将此查询复制到 SSMS 中并在那里声明和设置此参数会导致近乎即时的查询,因此它似乎不在数据库端。

有没有人遇到过可以解释正在发生的事情?我受第三方控件的摆布,该控件将此命令添加到查询中以尝试限制返回的行数,必须获取计数。这用于多个查询,因此需要一个通用解决方案。不幸的是,它不像宣传的那样工作,它似乎只会使查询花费 5-10 倍的时间,如果我只是将整个视图加载到内存中。但是,当不使用过滤器时,它就像做梦一样工作。

使用这些组件包括源代码,因此我可以更改此行为,但需要考虑可以使用哪些方法来提供可重用的解决方案。

您没有提到模型的设计细节,但是如果您只想根据条件进行记录计数,那么可以通过仅基于一列计算结果集来优化。例如

int count = context.viewCustomers.AsNoTracking().Where(c => c.Cust_ID == _custID).Count();

如果您设计有 10 列,并且基于上述语句,假设返回了 100 条记录,那么每个记录结果集包含 10 列的数据,这是无用的。

您可以通过仅基于单列对结果集进行计数来优化这一点。

int count = context.viewCustomers.AsNoTracking().Where(c => c.Cust_ID == _custID).Select(x=>new {x.column}).Count();

可以使用其他优化方法,例如使用计数CountAsync的异步变体。

相关内容

最新更新