2012-08-07 78 views
1

我试图优化一个需要大约6秒钟才能执行的查询。使用多个包含语句优化实体框架查询

string[] filters = ...; 

var data = 
    (from n in ctx.People 
     .Where(np => np.IsActive) 
    let isFilterMatch = filters.All(f => n.FirstName.ToLower().Contains(f) || 
             n.Prefix.ToLower().Contains(f) || 
             n.MiddleName.ToLower().Contains(f) || 
             n.LastName.ToLower().Contains(f) || 
             n.Information.Email.ToLower().Contains(f) || 
             (n.Address!= null && 
              (SqlFunctions.StringConvert((double)n.Address.Number). 
               Contains(f) || 
              n.Address.Street.ToLower().Contains(f) || 
              n.Address.ZipCode.ToLower().Contains(f) || 
              n.Address.City.ToLower().Contains(f)))) 
    where isFilterMatch 
    orderby n.LastName 
    select n 
    ).Take(numberOfItems).ToList(); 

这是查询搜索对话框。用户可以键入任何文本,然后搜索与输入相匹配的人员。我们将用户输入分割为一个字符串数组,然后在Person字段上执行Contains。由于过滤器数组,该查询无法预编译。

如何优化此功能?我听说过像Sql Server或存储过程的FullTextSearch。可以帮助吗?

我们使用的是Sql Server 2008,Entity Framework 4.0(Model First)和C#。

+0

您是否已将所有筛选字段的索引添加到数据库? – 2012-08-07 12:31:54

+0

@JustinHarvey我的列的类型为nvarchar(max)。我无法为它们添加索引。我得到这样的消息,即类型对索引中的键列无效。 – 2012-08-07 12:39:51

+0

@Wouter,我不明白你为什么需要'nvarchar(max)'为FirstName,MiddleName,LastName等。FirstName可以有多长?它应该是max nvarchar(50)如果没有其他的理由继续(最大) – Kashif 2012-08-07 12:53:15

回答

0

我不会对此搜索查询使用SQL查询/ Linq查询。对文本搜索的普通查询可能很慢,并且它们只返回确切的结果;他们不正确拼写/语法错误等。

您可能会考虑使用SQL Server的“全文搜索”功能;但由此产生的表现可能仍然很差。请参阅http://www.sql-server-performance.com/2010/full-text-search-2008/

我建议使用像Apache Lucene这样的搜索索引器(它可以在Lucene.NET中作为dll使用)。另一种选择是你编写自己的Windows服务,索引所有记录。