简体   繁体   English

Linq查询花费很长时间查询具有6000条记录的表

[英]Linq query taking a long time to query a table with 6000 records

I am having trouble with the performance of a query I am trying to write. 我在尝试编写查询的性能时遇到麻烦。 I have a table with about 6000 records within it. 我有一张桌子,里面有大约6000条记录。

Currently its taking about 15 seconds to run on my development machine. 目前,在我的开发计算机上运行大约需要15秒。 A win8 machine with 32gb ram quadcore running vs2012 & sql2012. 一款运行vs2012和sql2012的Win8机器,带有32GB ram四核。 So its not my machine its my bad code. 因此,这不是我的机器,而是我的错误代码。

    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();

The layout of the database tables are 数据库表的布局是

Business 商业

BusinessId BusinessId
Name 名称
etc 等等

StoreId 商店编号

StoreId 商店编号
StoreName 店铺名称
BusinessId BusinessId

Consumer 消费者

ConsumerId ConsumerId
FirstName 名字
LastName

ConsumerIdentities 消费者身份

BusinessId BusinessId
ConsumerIdentityType 消费者身份类型
ConsumerIdentityValue 消费者身份价值

Can anyone see any obvious things I am doing wrong that would be taking so long to return the query results? 谁能看到我做错的任何明显事情,而这些事情要花很长时间才能返回查询结果?

Turning on SQL Profiler was scary. 打开SQL事件探查器很可怕。 The first query made was to select everything from ConsumerIdentity table where the business Id matched. 进行的第一个查询是从Consumer Identity表中选择与业务ID相匹配的所有内容。 Great that's perfect then gets the business table table. 太完美了,然后获得了业务表表。

However then seems to make a call for every single record like 但是然后似乎为每条记录打电话

exec sp_executesql N'SELECT 
[Extent1].[ConsumerId] AS [ConsumerId], 
[Extent1].[UserID] AS [UserID], 
[Extent1].[FirstName] AS [FirstName], 
[Extent1].[LastName] AS [LastName], 
[Extent1].[IsMale] AS [IsMale], 
[Extent1].[DateOfBirth] AS [DateOfBirth], 
FROM [dbo].[Consumer] AS [Extent1]
WHERE [Extent1].[ConsumerId] = @EntityKeyValue1',N'@EntityKeyValue1     uniqueidentifier',@EntityKeyValue1='952ED7B8-2123-49E2-BAE3-69FBD713BACB'

So it looks like my where statement isn't getting applied 所以看起来我的where语句没有被应用

I would start with Customer (if the properties are present) because that saves a Distinct in the first place and it should do everything in one SQL statement: 我将从Customer(如果存在属性)开始,因为这首先保存了Distinct ,并且应该在一个SQL语句中执行所有操作:

from c in Customer
where c.FirstName.ToLower().Contains(containing.ToLower())
      && c.ConsumerIdentity.Business.StoreId == storeId
select c

This does not take away the where on c.FirstName.ToLower() . 这不拿走wherec.FirstName.ToLower() Such constructs always hit performance because they are not sargable (they eliminate any index). 这样的构造总是会影响性能,因为它们不可靠 (它们消除了任何索引)。 EF currently has no tooling to do case-insensitive search (it does not accept the Contains overload with an IEqualityComparer ), so technically you can't avoid this. EF当前没有工具来进行不区分大小写的搜索(它不接受IEqualityComparerContains重载),因此从技术上讲,您无法避免这种情况。 But chances are that the database collation is case insensitive, so x.FirstName.Contains(containing.ToLower() might give the same result, with index. 但是机会是数据库排序规则不区分大小写,因此x.FirstName.Contains(containing.ToLower()可能会给出带有索引的相同结果。

I just see one thing that can be improved: 我只是看到可以改进的一件事:

  • Use the Distinct after the Where ( Distinct is a O(n log n) Where in O(n)) Where之后使用DistinctDistinct是O(n log n)在O(n)中的Where

      consumers = business.ConsumerIdentities.Select(ci => ci.Consumer) .Where(x => x.FirstName.ToLower().Contains(containing.ToLower())) .Distinct() .ToList(); 

But I doubt your perfomance issue comes from the LINQ query (6000 records should be extremely fast in any case). 但是我怀疑您的性能问题来自LINQ查询(无论如何,6000条记录应该非常快)。

Does it help if you do the Select after the Where? 如果您在“之后”进行选择是否有帮助?

        consumers =
            business.ConsumerIdentities
                    .Where(x => x.FirstName.ToLower().Contains(containing.ToLower()))
                    .Distinct()
                    .Select(ci => ci.Consumer)
                    .ToList();

There are couple of ways to optimize that may decrease the process time (that other guys told) but any way you're query is doing a search process on a database with 6000 records. 有几种优化方法可以减少处理时间(其他人告诉我们),但是您要查询的任何方法都是在具有6000条记录的数据库上执行搜索过程。 But it should do it faster than 15sec for 6000 records. 但是它应该比15秒更快地完成6000条记录。

It may because of your memory cache. 可能是因为您的内存缓存。 I recommend clear your VS and system cache then try again. 我建议清除VS和系统缓存,然后重试。 (you can use C-Cleaner app for system cache) (您可以使用C-Cleaner应用程序进行系统缓存)

You can use Async in ADO too boots up. 您也可以在ADO中使用Async来启动。 It has a great effect in decreasing the process time. 它对减少处理时间有很大的作用。 (You can do it with IDataReadables and IDataReaders that support async) (您可以使用支持异步的IDataReadables和IDataReader来做到这一点)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM