C# Linq和.Count大型数据库

C# Linq和.Count大型数据库,c#,mysql,linq,C#,Mysql,Linq,我创建了asp mvc项目,该项目从大型Mysql数据库~500000获取数据 我使用单独的列过滤器将datatables添加到前端,其中只显示10个条目 工作又快又好 当我尝试在过滤器后添加计数以进行盘算时。无法工作服务器Mysql超时错误或工作非常缓慢 count = db.books.Count(x => (market_id == 0 || x.market_id != 0 && x.market_id == market_

我创建了asp mvc项目,该项目从大型Mysql数据库~500000获取数据

我使用单独的列过滤器将datatables添加到前端,其中只显示10个条目

工作又快又好

当我尝试在过滤器后添加计数以进行盘算时。无法工作服务器Mysql超时错误或工作非常缓慢

count = db.books.Count(x =>
                    (market_id == 0 || x.market_id != 0 && x.market_id == market_id)
                    && (name == null || x.name != null && (x.name.StartsWith(name)))
为什么数数不工作或这么慢


所有代码我的控制者

这一切都归结于数据库如何工作以及最终生成什么样的SQL。StartsWith被转换为通配符搜索,这可能比更简单的查询慢。您可以尝试放入索引,这将有助于您尝试优化的特定查询,并且您可以查看生成的SQL,以检查它是否如您所期望的那样好(有时它会生成奇怪的SQL,但这看起来像是一个足够简单的查询,所以我还不太担心)。如果添加括号分隔OR表达式的各个部分,例如
name==null | | |(x.name!=null&&(x.name.StartsWith(name))),您可能还需要检查生成的SQL中是否有任何差异。

您最好这样做:

var query = db.books.AsQueryable();

if (market_id!=0)
  query = query.Where(x=>x.market_id==market_id);

if (name!=null)
  query = query.Where(x=>x.name.StartsWith(name));

count = query.Count();
data = query
  .OrderBy(x=>x.id)
  .Skip(param.Start)
  .Take(10)
  .ToList();
并非所有LINQ提供程序都能很好地优化过滤器,并将其传递到数据库。许多数据库将为这些类型的查询生成糟糕的查询计划,并生成最坏情况最少的查询计划,并将其重新用于所有类似的查询,这将错过使用上述代码通常会使用的索引的可能性

在许多情况下,您可能还希望限制计数,因此您可以这样做:

count = query.Take(1001).Count();

然后,如果count==1001,则使用消息“超过1000个结果”。

Sql Server处理计数(也包括谓词)的速度往往非常快。无论计数是否快速,它可能在数据库引擎中根深蒂固。我不知道MySql,但我认为您缺少一些重要的索引。
count = query.Take(1001).Count();