C# IQueryable<;T>;列出<;T>;性能问题
我有下面的代码可以正常工作,但在性能方面有一些问题。通过调试,我可以看到,当代码出现在下面这一行时,需要10秒的时间才能完成C# IQueryable<;T>;列出<;T>;性能问题,c#,iqueryable,generic-list,C#,Iqueryable,Generic List,我有下面的代码可以正常工作,但在性能方面有一些问题。通过调试,我可以看到,当代码出现在下面这一行时,需要10秒的时间才能完成 List<T> queryableListdResult = queryableInitialResult.ToList(); List queryableListdResult=queryableInitialResult.ToList(); 基本上,下面的代码从数据库中的150000条记录中获取大约15000条文章 有人能建议一个更好的方法吗?谢谢 我
List<T> queryableListdResult = queryableInitialResult.ToList();
List queryableListdResult=queryableInitialResult.ToList();
基本上,下面的代码从数据库中的150000条记录中获取大约15000条文章
有人能建议一个更好的方法吗?谢谢
我的代码:
public static IQueryable<T> CategoryFilter<T>(IQueryable<T> queryable, int categoryFilterCount, RenderingContext rc, bool CategoryOR, string categoriesforQuery) where T : AbstractResult
{
if (!string.IsNullOrEmpty(categoriesforQuery))
{
string[] categoriesDefined = categoriesforQuery.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
List<T> listInitialResult = new List<T>();
foreach (string TaxonomyID in categoriesDefined) //e.g. entertainment, business
{
string categoryToCompare = TaxonomyID.ToString().Replace("{", "").Replace("}", "");
queryable = queryable.Where(i => i.alltags.Contains(categoryToCompare));
List<T> queryableListdResult = queryable.ToList();
listInitialResult.AddRange(queryableListdResult);
}
if (CategoryOR)
{
return listInitialResult.AsQueryable();
}
else
{
List<T> queryableFinalResult = (listInitialResult.GroupBy(x => x._Group).Where(g => g.Count() >= categoryFilterCount)
.Select(g => g.FirstOrDefault())).ToList();
return queryableFinalResult.AsQueryable();
}
}
else
{
return queryable;
}
}
public static IQueryable CategoryFilter(IQueryable queryable,int categoryFilterCount,RenderingContext rc,bool CategoryOR,string categoriesforQuery),其中T:AbstractResult
{
如果(!string.IsNullOrEmpty(categoriesforQuery))
{
string[]categoriesDefined=categoriesforQuery.Split(新字符[]{'|'},StringSplitOptions.RemoveEmptyEntries);
List listInitialResult=新列表();
foreach(categoriesDefined中的字符串TaxonomyID)//例如娱乐、商业
{
string categoryToCompare=TaxonomyID.ToString().Replace(“{”,“”)。Replace(“}”,“”);
queryable=queryable.Where(i=>i.alltags.Contains(categoryToCompare));
List queryableListdResult=queryable.ToList();
listInitialResult.AddRange(queryableListdResult);
}
if(分类商)
{
返回listInitialResult.AsQueryable();
}
其他的
{
List queryableFinalResult=(listInitialResult.GroupBy(x=>x.\u Group)。其中(g=>g.Count()>=categoryFilterCount)
.Select(g=>g.FirstOrDefault()).ToList();
返回queryableFinalResult.AsQueryable();
}
}
其他的
{
返回可查询;
}
}
试试这个。我把你的代码并行化了
public static IQueryable<T> CategoryFilter<T>(IQueryable<T> queryable1, int categoryFilterCount, RenderingContext rc, bool CategoryOR, string categoriesforQuery) where T : AbstractResult
{
if (!string.IsNullOrEmpty(categoriesforQuery))
{
string[] categoriesDefined = categoriesforQuery.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
ConcurrentBag<T> listInitialResult = new ConcurrentBag<T>();
Parallel.ForEach(categoriesDefined, (TaxonomyID) =>
{
string categoryToCompare = TaxonomyID.ToString().Replace("{", "").Replace("}", "");
var queryable = queryable.Where(i => i.alltags.Contains(categoryToCompare));
List<T> queryableListdResult = queryable.ToList();
for (int i = 0; i < queryableListdResult.Count; i++)
{
listInitialResult.Add(queryableListdResult[i]);
}
});
if (CategoryOR)
{
return listInitialResult.AsQueryable();
}
else
{
List<T> queryableFinalResult = (listInitialResult.GroupBy(x => x._Group).Where(g => g.Count() >= categoryFilterCount)
.Select(g => g.FirstOrDefault())).ToList();
return queryableFinalResult.AsQueryable();
}
}
else
{
return queryable;
}
}
public static IQueryable CategoryFilter(IQueryable queryable1,int categoryFilterCount,RenderingContext rc,bool CategoryOR,string categoriesforQuery),其中T:AbstractResult
{
如果(!string.IsNullOrEmpty(categoriesforQuery))
{
string[]categoriesDefined=categoriesforQuery.Split(新字符[]{'|'},StringSplitOptions.RemoveEmptyEntries);
ConcurrentBag listInitialResult=新ConcurrentBag();
Parallel.ForEach(categoriesDefined,(TaxonomyID)=>
{
string categoryToCompare=TaxonomyID.ToString().Replace(“{”,“”)。Replace(“}”,“”);
var queryable=queryable.Where(i=>i.alltags.Contains(categoryToCompare));
List queryableListdResult=queryable.ToList();
for(int i=0;ix.\u Group)。其中(g=>g.Count()>=categoryFilterCount)
.Select(g=>g.FirstOrDefault()).ToList();
返回queryableFinalResult.AsQueryable();
}
}
其他的
{
返回可查询;
}
}
另外,我使用了一个并发包,我相信这是一个无锁的问题。希望这有帮助 除了装载卡车数据。 在处理这一问题时,有一些技巧可以最大化EF上下文。 例如
Context.Configuration.AutoDetectChangesEnabled=false代码>
您的代码片段表明toList()可能会在每次迭代中执行。
你可能想找到一种不同的方法来获得
List queryableListdResult=queryableInitialResult.ToList()代码> 请考虑查询的数据量。假设每篇文章只有1kB的数据。您正在删除15k个实体,但仍在尝试从数据库中获取15MB的数据。假设一个10Mb/s的链路10秒在数据传输速率方面几乎是正确的
我建议您要么投影查询以避免提取不必要的数据,要么升级数据链接
但是,如果您需要的是代码更具响应性,那么实际上可以使用流式IEnumerable
。您只需使用DbSet.AsStreaming()
方法。这会将数据传输成本分摊到IEnumerator.Next()
的每个调用中。但是我警告您,数据传输本身将花费更长的时间,并且您将在传输的整个生命周期中保持datareader锁
把你的问题读得更透彻。您实际需要的是IQueryable.Concat
。有了它,您可以在每个IQueryable上过滤您想要的所有内容,然后将它们合并在一起,最后是.ToList()
它。推荐的诊断工具。运行Sql事件探查器以发现您的调用生成的实际Sql。您需要所有这些记录,还是可以在数据库中筛选出一些记录?似乎要返回的数据太多了。我知道你已经在筛选了,但15k记录仍然是一个很好的选择lot@SCB不,我不需要所有这些记录,这只是筛选列表的第一步。然后我将继续应用筛选器以减少记录数,而不是调用iQueryTable上的ToList,这将导致对您的数据存储执行查询。@SCB很好,但我在聚合多个iQueryTables时遇到了问题。因此,我将其转换为List,然后执行了一个“AddRange”…您是否对照原始代码检查了它,以查看性能是否得到了改进?Linq中没有太多开销(Linq基本上是for
循环和yield
语句),但有一些开销。任何显著的加速都是由于。您必须将当前环路的状态存储在