2012-11-29 57 views
0

我已經寫了一塊實驗室處理軟件,需要輸入數據,打破它,並將它發送到數據庫中正確的領域。數據庫表格非常大,並且有很多字段。在插入數據之前,我會在插入數據之前進行一次複製檢查(我們從多個來源獲取重複數據)。如何在插入之前加速複製檢查?

的系統的工作原理是解析傳入數據,填充LINQ到SQL對象。 dupe檢查通過在linq-to-sql對象列表上執行.where操作來選擇尚未在表中的對象。

例如...

input=list (of TableA) 'linq to sql objects 
output=input.where(function (x as TableA) not myDb.TableA.any(function(l as table) l.name=x.name, l.dob=x.dob..etc for 10 fields..).tolist 

的語法是有點神祕,但是這是我能找到執行上的LINQ to SQL對象和數據庫記錄的內部連接的唯一途徑。在我使用這種方法之前,我一行一行地執行了複製檢查,這種方法速度較慢。

據我瞭解,LINQ的是這個LINQ語句轉換到在服務器上運行的SQL語句。

我的問題是:有沒有辦法得到這個跑得更快?是否有理由期望寫出一條sql語句來執行重複數據刪除和運行傳統查詢會更快?這個陳述很慢,但它的工作原理是,通過單元測試並阻止這些模糊。我在尋找的東西更快,等效乾淨(不硬,我知道)或清潔劑...

+0

儘管不是您的問題的直接答案,但我用於類似(儘管不完全相同)的用例的一種技術是編寫一個存儲過程,它執行相應的創建/更新/忽略決策。這將移動所有的邏輯服務器端,以便只有一個SQL通信(存儲過程調用)由LINQ執行。如果你是網絡綁定的,這將有所幫助。 – SAJ14SAJ

+0

@ SAJ14SAJ我不完全明白。 linq查詢不會被轉換爲傳遞給服務器的單個sql語句嗎?我們正在慢速網絡上運行,所以如果情況並非如此,那麼這可能是阻礙(除了大數據庫) – bernie2436

+0

簡短的答案是:它取決於。在構造DataContext時,您可以通過將'TextWriter'傳遞給'Log'屬性來確切地知道它在做什麼。但是,根據情況,它可能會在提交插入檢查之前自行執行「此行是否需要更新」檢查。您的where子句肯定會執行查詢,然後LINQ將始終爲每個待處理的插入操作執行另一個SQL命令。網上有很多關於「LINQ sql優化」查詢的信息。 – SAJ14SAJ

回答

1

您可以上姓名,出生日期和....每個插入表格的基礎定義唯一索引,可能成功完成或引發唯一的違反約束的異常。所以在插入前你不需要任何檢查。我認爲這是最直接的方式。

+0

當然合適的索引將有所幫助。 – SAJ14SAJ

+0

其他人對此有何看法?我認爲這是最乾淨的,因爲它(1)確實可以防止欺騙,並且(2)消除了欺騙檢查操作=更少的代碼。另一方面,它將使用錯誤來指導流量控制 - 我聽說這是一個no no – bernie2436

+0

關於這個問題的一個很好的討論可以在這裏找到: http://stackoverflow.com/questions/1736146/ why-is-exception-handling-bad –

0

如果沒有其他進程要添加到SQL表那麼當您啓動該程序,你可以將表讀入一個HashSet。檢查本地HashSet。如果不在HashSet中,則將其添加到SQL表和HashSet中。即使在同一個物理盒子上運行,HashSet查找的速度也比SQL查詢快100倍。我用這個來做一些大的負載。

如果您只想在短時間內獲得成功,那麼您可以在開始時跳過從表中加載歷史記錄,或者只加載最後一個X.檢查HashSet,並且只有在HashSet中找不到,然後使用SP插入或跳過。並且週期性地將HashSet截斷爲X.

+0

我喜歡這個想法 - 但桌子可能太大了。當我回到工作崗位時,我會玩弄它。 – bernie2436

+0

如果表很大,那麼只做最後一個X.如果HashSet找到90%的配音,那麼您已經將90%的dup檢查消除到SQL。 – Paparazzi

+0

'只加載最後一個x'是否只是將最近添加的x個最近添加的項加載到表中?我是不是還要檢查桌子的其餘部分了嗎? – bernie2436

相關問題