C# 頻繁對數據庫操作,性能問題
1、與數據庫交互,創建一次連接,必然影響性能。
Connection.open(); 打開以后用完關閉Connection.close();就算你只打開一次連接,用過多以后,再close;
性能會比前者快很多倍,如果只有100條數據以內,那也過得去;如果數據量達到1000,那這樣性能也提升不上來;
Select、Insert、Update等語句,字符串連接起來,做一次執行。效率要可觀多了。如下:
command.Excu(Insert into Table(a,b,c)Values(1,2,3);Insert into Table(a,b,c)Values(1,2,3);Insert into Table(a,b,c)Values(1,2,3););
2、SqlBulkCopy
在做大批量數據插入的時候,如果用Insert into ... values (...)這種方式的話效率極低,批量插入方法。

1 private static long SqlBulkCopyInsert() 2 { 3 Stopwatch stopwatch = new Stopwatch(); 4 stopwatch.Start(); 5 DataTable dataTable = GetTableSchema(); 6 string passportKey; 7 for (int i = 0; i < count; i++) 8 { 9 passportKey = Guid.NewGuid().ToString(); 10 DataRow dataRow = dataTable.NewRow(); 11 dataRow[0] = passportKey; 12 dataTable.Rows.Add(dataRow); 13 } 14 SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(connectionString); 15 sqlBulkCopy.DestinationTableName = "Passport"; 16 sqlBulkCopy.BatchSize = dataTable.Rows.Count; 17 SqlConnection sqlConnection = new SqlConnection(connectionString); 18 sqlConnection.Open(); 19 if (dataTable!=null && dataTable.Rows.Count!=0) 20 { 21 sqlBulkCopy.WriteToServer(dataTable); 22 } 23 sqlBulkCopy.Close(); 24 sqlConnection.Close(); 25 stopwatch.Stop(); 26 return stopwatch.ElapsedMilliseconds; 27 } 28 29
使用SqlBulkCopy類進行數據插入其原理是采用了SQL Server的BCP協議進行數據的批量復制。這里我們先要建好一個DataTable(最好是通過DataAdapter來灌數據得到,因為這樣出來的DataTable就已經有跟數據表相同的列定義,可以免去之后Mapping Column的步驟),把要插入的數據加進這個DataTable中,然后用SqlBulkCopy的實例來插入到數據庫中。經過測試,SqlBulkCopy方法比直接用Sql語句插入數據的效率高出將近25倍。
另外批量導入SQL、MYSQL等數據是同樣的for循環,使用拼出來的sql或者使用參數的方式傳遞或者使用事務等不同方式的傳遞效率都不同。如果不使用SqlBulkCopy的方式的話,我測試下來做快遞是用一次事務來操作為最快。因為10000次的循環如果是每次提交,那么都有鏈接和停止數據庫的操作,或者說他包含了1000次的小事務處理。如果外面就一個事務的話效率肯定會高。
其它方案網上參考:

技術方案一: 利用數據庫訪問類調用存儲過程,利用循環逐條插入。很明顯,這種方式效率並不高。 技術方案二: 由於是考慮到大數據量的批量插入,於是想到了ADO.NET2.0的一個新的特性:SqlBulkCopy。有關這個的性能,很早之前我親自做過性能測試,效率非常高。這也是我推薦的技術方案。 技術方案三: 利用SQLServer2008的新特性--表值參數(Table-Valued Parameter)。表值參數是SQLServer2008才有的一個新特性,使用這個新特性,我們可以把一個表類型作為參數傳遞到函數或存儲過程里。不過,它也有一個特點:表值參數在插入數目少於 1000 的行時具有很好的執行性能。 技術方案四: 對於單列字段,可以把要插入的數據進行字符串拼接,最后再在存儲過程中拆分成數組,然后逐條插入。查了一下存儲過程中參數的字符串的最大長度,然后除以字段的長度,算出一個值,很明顯是可以滿足要求的,只是這種方式跟第一種方式比起來,似乎沒什么提高,因為原理都是一樣的。 技術方案五: 考慮異步創建、消息隊列等等。這種方案無論從設計上還是開發上,難度都是有的。 優勢對比: 方案一的效率最低,需要多次更新數據庫,方案四與方案一原理相同,只是將處理放到了存儲過程中,且在參數傳入前后需進行拼接和拆分,操作比較麻煩。用SQL2008數據庫時推薦使用方案四。 對比方案一、二、三,技術方案二的優勢還是蠻高的。無論是從通用性還是從性能上考慮,都應該是優先被選擇的,另外它的技術復雜度要比技術方案三要簡單一些,設想我們把所有表都創建一遍表值類型,工作量還是很大。 因此推薦大家使用第二種技術方案。