iT邦幫忙

0

C# Parallel.ForEach問題再次請教

  • 分享至 

  • xImage

https://ithelp.ithome.com.tw/questions/10214167

這是我之前問的問題最後面我遇到的問題大概解了,我是加了LOCK
並把裡面的值加到LIST裡並判斷有沒有值


ConcurrentStack<資料庫連線相關> sBachSQL = new ConcurrentStack<資料庫連線相關>();
string data = string.Empty;
List<string> previousDataList = new List<string>();

 try{
        Count = 0;
        SqlString = "";
        string[] lines = File.ReadAllLines(Path);

        if (lines != null && lines.Count() > 0)
        {
            Parallel.ForEach(lines, (item, loopState) =>
            {
                lock (_lock)
                {
                     if (!previousDataList.Contains(item.ToString()))
                     {
                         data = item.ToString();
                         previousDataList.Add(data);
                     }
                                          
                try
                {
                   //解析並回傳更新的SQL語法
                   SqlString = RerurnSqlString(data);
                }
                catch (Exception exc)
                {
                                
                }
             if (SqlString.Trim() != "")
             {                               
                 sBachSQL.Add(SqlString);                               
                 Count++;
             }
              //每1000筆執行一次交易
             if ((Count == 1000))
             {
                 ExecuteTransaction(SqlString);
                 Count = 0;
                 SqlString = "";
                 sBachSQL = new ConcurrentBag<資料庫連接相關CLASS>();                           
              }
            }          
           });
       }
       
       if ((Count !=0))
       {
         ExecuteTransaction(SqlString);
         Count = 0;
         SqlString = "";
         sBachSQL = new ConcurrentBag<資料庫連接相關CLASS>();                           
       }
    }  

目前確定lines裡讀取的相關資料都有做到更新
可是因為加了LOCK的關係,整體效能基本上跟沒使用並行差不多
不用LOCK的話則只使用了一半的時間,但不是每一筆資料皆有更新
想請問這部分我能怎麼調整呢?
上次提問有人建議我可以使用SqlBulkCopy,但看他好像不能做更新QQ

天黑 iT邦研究生 5 級 ‧ 2023-09-26 16:47:58 檢舉
SqlBulkCopy 你是說update語法嗎? 有高手寫好的文章可以參考 https://dotblogs.com.tw/supershowwei/2016/12/09/221622、https://dotblogs.com.tw/supershowwei/2016/12/30/154257
tenno081 iT邦研究生 4 級 ‧ 2023-09-26 17:00:08 檢舉
比較麻煩的是我這邊用的ORACLE,這兩篇我有看過QQ
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 個回答

1
一級屠豬士
iT邦大師 1 級 ‧ 2023-09-27 11:07:49

Oracle 有 external table, Oracle 的多年的載入外部資料工具 SQL*Loader
將資料載入後,建立一個暫存或是日期流水命名的 table ,再做處理,這時候有 upsert
https://docs.oracle.com/en/database/other-databases/nosql-database/21.1/sqlfornosql/adding-table-rows-using-insert-and-upsert-statements.html#GUID-2C68AD4C-B804-4562-8C6B-AD05AE21AB6C

或是使用 merge https://docs.oracle.com/en/database/oracle/oracle-database/12.2/sqlrf/MERGE.html#GUID-5692CCB7-24D9-4C0E-81A7-A22436DC968F

就可以很方便快速的根據上面建立的table,來去異動其他table.

--
用程式迴圈一筆筆讀,然後再一道道SQL 去異動, 這個好處是程式會變的很多隻,
也都跑很慢,增加地球的二氧化碳.但是這是很多人這樣做啦,而且還認為這是唯一的方法.
原本我是不太想寫上面那些啦.一來容易得罪人,二來你若是這樣做,可能會破壞你們
皇城裡的和諧,反而對你不好.

tenno081 iT邦研究生 4 級 ‧ 2023-09-27 11:36:58 檢舉

你好,我們是迴圈跑完後會產生SQL的語法然後每1000筆執行一次,目前是跑一萬多筆大概四分鐘跑完,想看看能不能再調整,因為我們是用dapper所以目前不太確定能不能用這方法實現,我找一下資料看看,乾蝦~

我要發表回答

立即登入回答