2012年3月20日 星期二

C# 見鬼了【這些資料目前沒有唯一的值】?


原本我寫了一段程式來產生一個 mapping 用的 DataTable,
程式碼如下:

DataTable mappingValue = SystemFuncs.GetTableByQuery(
    "SELECT key_, import_value_, mapping_value_ FROM import_mapping_item ");

DataColumn[] keys = new DataColumn[2]{mappingValue.Columns[0], mappingValue.Columns[1]};

mappingValue.PrimaryKey = keys;

某天突然就發生了錯誤,錯誤訊息如下:


2012年3月15日 星期四

SqlDataAdapter.UpdateBatchSize


今天客戶反應說匯入程式的效能不好,
他說匯入四千多筆資料要 3 分鐘左右,
個人是覺得四千多筆資料 3 分鐘應該是可以接受的範圍吧?
不過客戶說覺得不好也只能調整看看了!
客戶查了資料發現,其實資料寫入 Local 的 DataTable 其實花不到 3 秒鐘,
所以大部分的時間應該是卡在從 DataTable 寫入 DB 的時間,
個人是覺得這個我好像沒甚麼好調整的吧?
不過在我本機測試了一下,
發現不管我怎麼測,通通都沒有超過 1000 毫秒?
這樣表示其實也不是寫入 DB 的速度慢囉?
那麼是客戶端網路環境的關係嗎?

在無聊亂看的時候發現有 SqlDataAdapter.UpdateBatchSize 這個參數可以調整,
這個參數是來調整一次要一筆寫入還是整批寫入,
然後可以調整一批的數量的參數。
不過匯入程式是一次把四千多筆資料一次丟上去,
然後呼叫 SqlDataAdapter.Update 來寫入DB的,
這樣他不會一次一整批寫入嗎?
查了半天,沒找到哪邊有提到他的預設值是甚麼?
直接 Debug 看他的值才發現預設是 1 ㄟ
只怪我把世界想的太美好了!
查了一下 SqlDataAdapter.UpdateBatchSize 要怎麼用,
說明裡面有說:



將其設為大於 1 的值時,與 SqlDataAdapter 相關聯的所有命令都必須將其 UpdatedRowSource 屬性設為 None OutputParameters。否則會擲回例外狀況。


不過我照著寫

SqlDataAdapter.UpdateCommand.UpdatedRowSource = UpdateRowSource.None;



卻會有錯誤訊息!
所以我最後只有加寫了一行

SqlDataAdapter.UpdateBatchSize = 10000;



目前看起來單筆修改跟整批匯入的 Update 都沒有問題,
似乎是有比較快一點,接下來就看客戶那邊有沒有變快囉!