7

我有一个列表:集合用户,其中包含大约 100K+ 用户记录(所有用户对象都从数据库中完全加载,其中包含生物、名字、姓氏等字段)。此集合在应用程序启动时从数据库中获取并保存在内存中。

然后我有如下代码:

User cachedUser = users.FirstOrDefault(x => string.Equals(x.UserName, username,
StringComparison.CurrentCultureIgnoreCase));

我用来从这个集合中获取用户。但不知何故,我注意到这个操作非常慢。使用 Linq 查询大对象的内存集合时是否存在性能问题?每次我想获得用户时,我是否应该调用数据库?

4

4 回答 4

8

我认为您可能需要根据您提供给我们的信息重新考虑您的架构。利用数据库,让它为您完成搜索工作。之后观察、测量并做出相应的改变。你可能会意识到你过早地优化了整个事情。

于 2012-06-20T17:03:37.703 回答
3

与任何其他迭代技术(循环、在数组中搜索)一样,您的 LINQ 查询将访问每条记录,直到找到所请求的记录。在最坏的情况下,这意味着 10 万次比较。为了加快速度,您有以下选择:

  1. 使用排序列表或字典:二进制搜索要快得多。使用 ORDER BY 从数据库中获取数据时对数据进行排序
  2. 使用数据集。它就像一个提供更快搜索的内存数据库
  3. 将数据留在数据库中并设置适当的索引以便更快地访问

由于以下原因,我建议使用数据库:

  • 存储 100k 条记录是浪费内存,您可能从不使用这些记录
  • 更改数据后,您将不得不刷新缓存,这可能相当复杂
  • Web 应用程序是多线程的(每个请求都在自己的线程中运行)。如果您更改数据,则必须与锁同步。
  • 数据库可以缓存经常调用的数据
  • 你必须写更少的代码
  • 您有一个可扩展性更好的无状态 Web 应用程序(网络农场)
  • 您的应用程序可能还有其他数据,您无法将所有内容存储在内存中
于 2012-06-20T16:55:01.763 回答
3

如果您想优化您的响应时间,您可以创建一个Dictionary<T,U>并在以下范围内搜索用户:

    Dictionary<string, User> usersDictionary = new <Dictionary<string, User>(StringComparer.CurrentCultureIgnoreCase);

    // After querying the users from the DB add them to the dictionary             
    usersDictionary.Add(user.UserName, user);

    // Then when you need to retrieve a user
    User retrieveUser = null; 
    usersDictionary.TryGetValue(username, out retrieveUser);

希望有帮助!

于 2012-06-20T17:03:09.507 回答
0

您注意到的搜索性能的不同是因为数据库使用索引来定位数据库中的字符串,但是您在内存中简单地搜索所有记录,直到找到一条。此外,数据库为字符串保留一个哈希数并搜索这个数字哈希,速度要快得多,而不是实际进行字符串比较。

make也是一个索引,Dictionary<>但是添加数据有延迟,当数据开始增长时,因为当它添加一些数据时,每次都是搜索将它放置在正确的索引点的位置。

此外,数据库缓存结果,许多数据库还缓存索引并创建额外的统计信息,有助于快速定位您要查找的内容。

最好让数据库进行搜索,除非您可以为额外的自定义案例更快地进行搜索。

于 2012-06-20T19:03:36.103 回答