2011-05-17 47 views
2

我有進口產品註冊的日常文件,並將它們添加到我們的數據庫的過程。最初這個過程會針對每個記錄多次查詢數據庫以確定如何處理數據。加快通過詞典循環在VB.Net 2008

爲了加快這一過程並防止任何人嘗試使用使用相同數據庫的報告站點可能會出現的超時問題,我更改了代碼以將一些表格拖入字典中,然後遍歷它們以查看該客戶/地址/經銷商是否存在,並且如果確實存在,則從該字典的關鍵字中提取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 

這本詞典中有大約11萬條記錄。

一個想法我的一個同事曾是循環之前運行Dictionary.ContainsValue(),看看它甚至在那裏。如果它不是完全跳過循環。我只想嘗試一下,如果運行速度比只執行循環本身更快,如果他們採取相同的時間,我沒有看到基本上運行循環兩次的一個點。

所以我的問題給你:

  • 我在最 effiecient的方式去這件事?
  • 會是更快 運行Dictionary.ContainsValue()試圖循環,或將 系統將其解釋爲同樣的事情 ,因此我加倍的時間之前 ?
  • 還有什麼,我應該尋找?
+2

您正在計算'firstName&「|」 &lastName&「|」 &companyName&「|」 &addrId&「|」 &typeID&「|」 &phone&「|」和電子郵件「1100萬次?在循環之前嘗試計算一次。 – Gabe 2011-05-17 21:24:52

+0

@加貝,你擊敗了我50秒! – 2011-05-17 21:26:27

+0

Dictionary.Values總是唯一的嗎?如果是這樣,反轉鍵值對(如幾個響應註釋)是一個好主意。 – clweeks 2011-05-17 21:39:08

回答

5

一個明顯小的優化將是外循環執行firstName串聯,lastName一次。目前,您在循環的每次迭代中連接,顯然比它可能慢。

不,使用ContainsValue不會更快 - 仍然必須進行線性搜索。

明顯的優化將反轉字典 - 創建一個Dictionary(Of String, Int64)基本上有每個字符串值的ID。目前你沒有使用字典的天然優勢 - 你基本上把它看作是一個鍵/值對列表。

你是否真的使用字典正常方式以及(按鍵查找)?

1

有一兩件事你可以做,以加快速度是預先CONCAT該搜索字符串:

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

它看起來像你以相反的方式使用字典它應該如何使用 - 或者我錯過了什麼?

通過循環鍵,在字典中值對,你抵消一個字典(哈希表)提供的好處 - 一個給定鍵值的快速查找。

你應該使用(字符串,Int64的)的字典,映射firatname,姓氏,......到CUSTID。與你目前正在做的事情相比,對此進行查找會非常快速。

1

使用字典的目的是快速查找KEY沒有價值。無論是隻使用一個正常的數組列表或更改您的代碼,以便您進行密鑰查找而不是查找值。

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是你用新產品傳入的表值參數。您可能需要在這些字段上創建某種索引來加速比較,因爲您似乎沒有可比較的鍵。