C# Linq查询查询6000条记录的表需要很长时间
我试图编写的查询的性能有问题。我有一张表,里面有大约6000条记录 目前在我的开发机器上运行大约需要15秒。运行vs2012和sql2012的32gb ram四核win8计算机。所以这不是我的机器,而是我的坏代码C# Linq查询查询6000条记录的表需要很长时间,c#,linq,entity-framework,linq-to-entities,C#,Linq,Entity Framework,Linq To Entities,我试图编写的查询的性能有问题。我有一张表,里面有大约6000条记录 目前在我的开发机器上运行大约需要15秒。运行vs2012和sql2012的32gb ram四核win8计算机。所以这不是我的机器,而是我的坏代码 public IEnumerable<Customer> GetByStoreIdAndContainingName(Guid storeId, string containing) { using (var context = new En
public IEnumerable<Customer> GetByStoreIdAndContainingName(Guid storeId, string containing)
{
using (var context = new Entities())
{
var store = context.Stores.FirstOrDefault(b => b.StoreId == storeId);
if (store == null) return null;
var business = store.Business;
var consumers = new List<Consumer>();
consumers =
business.ConsumerIdentities.Select(ci => ci.Consumer)
.Distinct()
.Where(x => x.FirstName.ToLower().Contains(containing.ToLower()))
.ToList();
所以我的where语句似乎没有得到应用我只看到了一件可以改进的事情:
- 在
后面使用Where
(Distinct
是一个O(n log n)Distinct
在O(n)中)Where
但我怀疑您的性能问题来自LINQ查询(6000条记录在任何情况下都应该非常快)。我只看到一件可以改进的事情:
- 在
后面使用Where
(Distinct
是一个O(n log n)Distinct
在O(n)中)Where
但是我怀疑您的性能问题来自LINQ查询(6000条记录在任何情况下都应该非常快)。如果您在Where之后进行选择是否有帮助
consumers =
business.ConsumerIdentities
.Where(x => x.FirstName.ToLower().Contains(containing.ToLower()))
.Distinct()
.Select(ci => ci.Consumer)
.ToList();
如果在Where之后选择,是否有帮助
consumers =
business.ConsumerIdentities
.Where(x => x.FirstName.ToLower().Contains(containing.ToLower()))
.Distinct()
.Select(ci => ci.Consumer)
.ToList();
我将从Customer开始(如果属性存在),因为这首先会保存一个
不同的,并且它应该在一个SQL语句中完成所有操作:
from c in Customer
where c.FirstName.ToLower().Contains(containing.ToLower())
&& c.ConsumerIdentity.Business.StoreId == storeId
select c
这不会删除c.FirstName.ToLower()
上的where
。这样的构造总是会影响性能,因为它们不是(它们消除了任何索引)。EF目前没有用于执行不区分大小写搜索的工具(它不接受带有IEqualityComparer
的Contains
重载),因此从技术上讲,您无法避免这种情况。但数据库排序规则可能不区分大小写,因此x.FirstName.Contains(containing.ToLower()
可能会给出相同的结果,带有索引。我将从Customer开始(如果属性存在),因为这首先会保存一个Distinct
,并且它应该在一个SQL语句中完成所有操作:
from c in Customer
where c.FirstName.ToLower().Contains(containing.ToLower())
&& c.ConsumerIdentity.Business.StoreId == storeId
select c
这并没有去除c.FirstName.ToLower()
上的where
。这样的构造总是能达到性能,因为它们没有(它们消除了任何索引)。EF目前没有工具来进行不区分大小写的搜索(它不接受包含重载和IEqualityComparer
),所以从技术上讲,您无法避免这种情况。但数据库排序规则可能不区分大小写,因此x.FirstName.Contains(containing.ToLower()
可能会给出相同的结果,带有索引。有几种优化方法可以减少处理时间(其他人告诉过)但不管怎样,查询都是在一个有6000条记录的数据库上进行搜索。
但对于6000条记录,它的速度应该超过15秒
这可能是因为您的内存缓存。
我建议您清除VS和系统缓存,然后重试。(您可以使用C-Cleaner应用程序进行系统缓存)
您也可以在ADO启动中使用异步。
它在减少处理时间方面有很大的作用。(您可以使用支持异步的IDataReadables和IDataReaders来实现)有几种优化方法可以减少处理时间(其他人告诉过),但任何查询方法都是在一个有6000条记录的数据库上执行搜索过程。
但对于6000条记录,它的速度应该超过15秒
这可能是因为您的内存缓存。
我建议您清除VS和系统缓存,然后重试。(您可以使用C-Cleaner应用程序进行系统缓存)
您也可以在ADO启动中使用异步。
它在减少处理时间方面有很大的作用。(您可以使用支持异步的IDataReadables和IDataReaders来实现)我首先在microsoft sql server management studio中查看实际的sql查询及其执行计划(您可以使用sql profiler跟踪查询)。尝试在发行版中运行(不带任何调试标志)配置(如果不存在):Reader或使用此调试可视化工具:这些表上有哪些索引?目前我在这些表上没有任何索引。我现在将尝试添加这些索引。我将首先在microsoft sql server management studio中查看实际的sql查询及其执行计划(您可以使用sql profiler跟踪查询)。尝试在版本中运行(不带任何调试标志)如果没有,请配置Reader或使用此调试可视化工具:这些表上有什么索引?目前我在这些表上没有任何索引。我将尝试添加这些nowConsumer包含FirstName,因此where will failConsumer包含FirstName,因此where will failI对此进行了更新,因为从最终实体objec开始t(大多数时候)是个好主意。我对此投了赞成票,因为从最终实体对象开始的想法(大多数时候)是个好主意。