在字符串列表中搜索字符串的最有效方法是什么?

时间:2011-04-07 08:35:54

标签: sql-server string c#-4.0

我正在使用C#开发自定义电子邮件客户端。明显的要求之一是我不下载已经下载的消息。这是通过将唯一ID字符串与存储在我的数据库中的消息进行比较来完成的。

数据库存储多个用户和多个帐户的电子邮件,因此唯一ID在我的数据库中不一定是唯一的。

目前我有这样的事情:

List<String> DownloadedUIDs = BLL.EmailsDataSource.ViewEmailUIDs(AccountNo);     
foreach (string uid in serveruids) {
   if (DownloadedUIDs.Contains(uid)) continue; // don't download messages we already have  
   ...
}

我知道Contains()方法执行的线性搜索非常低效。如果服务器上存储了5000封电子邮件,则需要在5000封电子邮件列表中进行5000次线性搜索,以确定该电子邮件是否已存在。

我是否会看到更好的性能要求SQL Server订购唯一ID,然后对它们执行二进制搜索,或将唯一ID存储在哈希表中?或者使用其他一些数据结构?

有没有人知道任何类似的性能比较?

4 个答案:

答案 0 :(得分:0)

我的建议是以下两个之一:

  1. 借助索引在数据库中执行搜索,该索引包含一起构成唯一ID的所有列。搜索是一个简单的选择。
  2. 使用Hashmap。

答案 1 :(得分:0)

您可以将消息存储在由其uid索引的二叉树结构中。这样,如果您最终尝试添加已存在的消息,您将点击案例current_node.uid == new_node.uid并将其作为副本丢弃。

通过这种方式,您的系统可以进行更少的更改,您可以享受b树的性能! = d

答案 2 :(得分:0)

我知道以下回复未明确回答您的问题。但是,我相信它确实回应了你的问题的核心,这个问题涉及在保持质量系统性能的同时不允许数据库表中的重复记录。

不要在插入电子邮件之前检查重复的电子邮件,而应考虑/测试以下逻辑:

  1. 指定唯一键约束 你的电子邮件数据库表
  2. 尝试/捕获您的INSERT语句 独特的违规行为
  3. 此方法不仅保证避免重复的电子邮件,还避免了您提到的线性搜索问题。

    虽然与SELECT检查相比,此方法可能会产生轻微的性能损失,但只有在捕获到违规时才会这样做。因此,如果您认为重复电子邮件的可能性非常低(一个真正的例外),那么您可能会发现与SELECT检查相比,此方法最有效(并且万无一失)。

    为了支持我的观点,请查看Paul Nielsen的“10 Lessons from 35k tps”列表中的“第4课”

答案 3 :(得分:0)

我决定进行一些性能测试,这些是我得到的结果(从连接到邮件服务器到验证已经下载的所有3000封电子邮件):

  1. 未排序列表= 418ms
  2. 排序列表= 329毫秒
  3. 排序集= 312毫秒
  4. 排序列表+二进制搜索= 310毫秒
  5. HashSet = 305ms
  6. 所以看来我的数据至少表明HashSets在这方面最快,尽管在所有4种优化方法之间几乎没有选择。