我有一个导入每日产品注册文件的流程,并将它们添加到我们的数据库中。最初,此过程将针对每个记录多次查询数据库,以确定如何处理数据。
为了加快此过程并防止尝试使用使用相同数据库的报告网站的人可能出现的任何超时问题,我已更改代码以将一些表下拉到词典中,并且然后迭代它们以查看该客户/地址/经销商是否存在,如果是,则从字典的键中提取Id,或者将其插入表中,如果不存在则插入字典。
但是,我目前发现这比运行慢要比每次注册多次查询数据库一样。我能想到的一个可能原因是我的词典非常庞大(一个有800万个条目,另一个有1100万个)。
以下是我正在做的一个例子:
For Each kvp As KeyValuePair(Of Int64, String) In dCust
If kvp.Value = firstName & "|" & lastName & "|" & companyName & "|" & addrId & "|" & typeID & "|" & phone & "|" & email Then
custId = kvp.Key
Exit For
End If
Next
这本词典里面有大约1100万条记录。
我的一个同事的想法是在循环之前运行Dictionary.ContainsValue()
以查看它是否在那里。如果它不完全跳过循环。我只想尝试这个,如果它运行得比只执行循环本身更快,如果他们花了相同的时间我没有看到基本上运行循环两次的一点。
所以我的问题是:
Dictionary.ContainsValue()
尝试循环,或将
系统将它们解释为相同
事情,因此加倍我的时间?答案 0 :(得分:5)
一个明显的小优化是在循环外执行firstName
,lastName
等的连接。目前你在循环的每次迭代中连接,这显然比它可能更慢。
不,使用ContainsValue
并不会更快 - 仍然需要进行线性搜索。
显而易见的 big 优化是反转字典 - 创建一个Dictionary(Of String, Int64)
,它基本上具有每个字符串值的ID。目前,您没有使用字典的自然优势 - 您实际上将其视为键/值对列表。
您是否实际使用普通方式的字典(按键查找)?
答案 1 :(得分:3)
看起来你正在使用字典的方式与它应该如何使用 - 或者我错过了什么?
通过遍历字典中的键值对,您将使字典(散列表)提供的好处无效 - 快速查找给定键值的好处。
您应该使用(String,Int64)字典,将firatname,lastname,...映射到custId。与您目前正在进行的操作相比,查找此内容非常快。
答案 2 :(得分:1)
你可以做的一件事就是加速搜索字符串:
Dim SearchValue as String = firstName & "|" & lastName & "|" & companyName & "|" & addrId & "|" & typeID & "|" & phone & "|" & email
For Each kvp As KeyValuePair(Of Int64, String) In dCust
If kvp.Value = SearchValue Then
custId = kvp.Key
Exit For
End If
Next
答案 3 :(得分:1)
使用字典的目的是快速查找 KEY 而不是值。要么只使用普通的数组列表,要么更改代码,以便进行密钥查找而不是值查找。
答案 4 :(得分:0)
我认为关于字典的答案很棒,但我认为更广泛的答案是在数据库层处理这些东西而不是下载数百万条记录来迭代使用C#中的字典。为什么不使用table valued parameter(我假设您正在使用SQL Server 2008)传递您想要比较的数据并查看它是否存在?你将它传递给存储过程或者在SQL端进行比较的东西。你甚至可以这样做:
INSERT ProductRegistrations
SELECT * FROM @tvpProductsToAdd pa WHERE
pa.firstName + pa.lastName + pa.companyName NOT IN
(SELECT firstName + lastName + companyName FROM ProductRegistrations)
@tvpProductsToAdd是您在新产品中传递的表值参数。您可能希望在这些字段上创建某种索引以加快比较速度,因为您似乎没有可以比较的键。