搜索大量文本列表的最快方法

我有一个用C#编写的Windows应用程序需要从数据库加载250,000行,并提供“键入时搜索”function,这意味着只要用户在文本框中键入内容,应用程序就需要搜索所有250,000条记录(其中是btw,单列,每行1000个字符)使用like search并显示找到的记录。

我遵循的方法是:

1-应用程序将所有记录加载到类型化的List

 while (objSQLReader.Read()) { lstEmployees.Add(new EmployeesData( Convert.ToInt32(objSQLReader.GetString(0)), objSQLReader.GetString(1), objSQLReader.GetString(2))); } 

2-在TextChanged事件中,使用LINQ ,我搜索(结合使用正则表达式)并将IEnumerable附加到处于虚拟模式的ListView。

 String strPattern = "(?=.*wood*)(?=.*james*)"; IEnumerable lstFoundItems = from objEmployee in lstEmployees where Regex.IsMatch(Employee.SearchStr, strPattern, RegexOptions.IgnoreCase) select objEmployee; lstFoundEmployees = lstFoundItems; 

处理3-4 RetrieveVirtualItem事件以显示ListView中的项目以显示该项目。

 e.Item = new ListViewItem(new String[] { lstFoundEmployees.ElementAt(e.ItemIndex).DateProjectTaskClient, e.ItemIndex.ToString() }); 

虽然从SQL Server加载列表相对较快(1.5秒)加载lstEmployees ,但要在TextChanged上搜索,使用LINQ搜索需要7分钟以上。 通过执行LIKE搜索直接搜索SQL Server只需不到7秒。

我在这做错了什么? 如何更快地进行此搜索(不超过2秒)? 这是我的客户的要求。 所以,任何帮助都非常感谢。 请帮忙…

存储文本数据的数据库列是否有索引? 如果是这样的话,类似于尼古拉斯描述的trie structure东西已经被使用了。 SQL Server中的索引是使用B+ trees实现的, B+ trees的平均搜索时间大约为n的log base 2,其中n是树的高度。 这意味着如果表中有250,000条记录,则搜索所需的操作数是log base 2(250,000)或大约18个操作。

当您将所有信息加载到数据读取器中然后使用LINQ表达式时,它是线性操作,(O)n,其中n是列表的长度。 最糟糕的情况是,这将是250,000次操作。 如果使用DataView,则会有可用于帮助搜索的索引,这将大大提高性能。

在一天结束时,如果不会有太多针对数据库服务器提交的请求,请利用查询优化器来执行此操作。 只要LIKE操作不是在字符串前面使用通配符(即LIKE %some_string )(否定使用索引)并且表上有索引,您将获得非常快的性能。 如果有太多请求将被提交到数据库服务器,则将所有信息放入DataView以便可以使用索引,或者使用上面提到的Tim的字典,其搜索时间为O(1 )(大约一),假设字典是使用哈希表实现的。

你想要预先加载东西并建立一个叫做trie的数据结构

特里,还有其他什么?

这是记忆密集型的,但这是医生在这种情况下所要求的。

看看我对这个问题的回答 。 如果您需要即时响应(即与用户类型一样快),将数据加载到内存中是一个非常有吸引力的选择。 它可能会使用一点内存,但速度非常快。

即使有很多字符(250K记录* 1000),有多少个唯一值? 基于键的内存结构与指向匹配这些键的记录的指针实际上不一定非常大,甚至可以考虑这些键的排列。

如果数据确实不适合内存或经常更改,请将其保存在数据库中并使用SQL Server全文索引,这将比LIKE更好地处理此类搜索。 这假设从应用程序到数据库的快速连接。

全文索引提供了一组强大的运算符/表达式,可用于使搜索更加智能化。 它可以使用免费的SQL Expression Edition,它可以处理多达10GB的数据。

如果可以对记录进行排序,您可能希望使用二进制搜索,这对于大型数据集来说要快得多。 .NET集合中有几种实现,如ListArray