測試環境
- 硬體:Dell 2850 雙核 2.0 GHz、2 GB RAM
- 資料:100 萬列,單欄
Value1
- 工具:VS 2008 + IsLine Framework DataProvider
- 目標表:
TableB (Value1 VARCHAR(...))
五種方法與耗時 (毫秒)
| # | 方法 | SQL 2000 | SQL 2008 | 關鍵參數 |
| 1 | 基本 INSERT (10 萬/批次,10 批次) | 901,599 | 497,638 | 單列 INSERT,每 10 萬 Commit |
| 2 | BULK INSERT (文字檔) | 4,009 | 10,722 | BATCHSIZE=100000,FIELDTERMINATOR=',',ROWTERMINATOR='|' |
| 3 | 多執行緒 BULK INSERT (5 執行緒,各 20 萬) | 21,099 | 10,997 | 每 5 萬 Commit,並行度 5 |
| 4 | SqlBulkCopy 類別 | 4,989 | 10,412 | BatchSize=100000,BulkCopyTimeout=60,ColumnMappings |
| 5 | 多執行緒 SqlBulkCopy (5 執行緒) | 7,682 | 10,870 | 同上,並行度 5 |
關鍵發現
- SQL 2000 下 BULK INSERT 單執行緒最快 (4 秒),遠優於 SqlBulkCopy
- SQL 2008 表現反而較慢 (約 10 秒),可能因預設檢查條件約束、觸發器、記錄模式等預設值不同
- 多執行緒在 SQL 2000 有顯著提升 (BULK INSERT 21 秒 → 4 秒?實測單執行緒更快,可能受磁碟爭用影響),SQL 2008 則無明顯差異
BATCHSIZE / BatchSize 設定 10 萬平衡記錄檔成長與交易成本
程式碼片段 (SqlBulkCopy)
using (var sqlBC = new SqlBulkCopy(conn))
{
sqlBC.BatchSize = 100000;
sqlBC.BulkCopyTimeout = 60;
sqlBC.DestinationTableName = "dbo.TableB";
sqlBC.ColumnMappings.Add("valueA", "Value1");
sqlBC.WriteToServer(dt); // dt 為預先填充的 DataTable
}
建議
- 大量匯入首選 BULK INSERT (T-SQL) 或 SqlBulkCopy (程式碼控制)
- 生產環境先在測試機基準測試,調整批次大小、平行度、復原模式 (大量匯入時可暫設
BULK_LOGGED)
- 關閉非必要索引/觸發器/條件約束,匯入完成後重建
- 使用
TABLOCK 提示減少鎖升級