日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

为什么 Dapper 的批量插入比我预期的要慢很多?

發布時間:2023/12/4 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 为什么 Dapper 的批量插入比我预期的要慢很多? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

咨詢區

  • kenwarner

我的項目中有一個批量插入的需求,我采用的是 Dapper 連接數據庫,下面是我的代碼。

var?members?=?new?List<Member>(); for?(int?i?=?0;?i?<?50000;?i++) {members.Add(new?Member(){Username?=?i.toString(),IsActive?=?true}); }using?(var?scope?=?new?TransactionScope()) {connection.Execute(@" insert?Member(Username,?IsActive) values(@Username,?@IsActive)",?members);scope.Complete(); }

上面代碼插入需要 20s,插入量大概 2500/s,雖效果還行,但我在網上找的文章說可以做到 45k/s ,請問如何做到這么高的插入量?

回答區

  • Fredrik Ljung

下面是我批量插入的最佳實踐,可以實現 50k 條數據 4s 搞定。

SqlTransaction?trans?=?connection.BeginTransaction();connection.Execute(@" insert?Member(Username,?IsActive) values(@Username,?@IsActive)",?members,?transaction:?trans);trans.Commit();
  • CallumVass

我實現了一個可批量插入的擴展方法,參考代碼如下:

public?static?class?DapperExtensions {public?static?async?Task?BulkInsert<T>(this?IDbConnection?connection,string?tableName,IReadOnlyCollection<T>?items,Dictionary<string,?Func<T,?object>>?dataFunc){const?int?MaxBatchSize?=?1000;const?int?MaxParameterSize?=?2000;var?batchSize?=?Math.Min((int)Math.Ceiling((double)MaxParameterSize?/?dataFunc.Keys.Count),?MaxBatchSize);var?numberOfBatches?=?(int)Math.Ceiling((double)items.Count?/?batchSize);var?columnNames?=?dataFunc.Keys;var?insertSql?=?$"INSERT?INTO?{tableName}?({string.Join(",?",?columnNames.Select(e?=>?$"[{e}]"))})?VALUES?";var?sqlToExecute?=?new?List<Tuple<string,?DynamicParameters>>();for?(var?i?=?0;?i?<?numberOfBatches;?i++){var?dataToInsert?=?items.Skip(i?*?batchSize).Take(batchSize);var?valueSql?=?GetQueries(dataToInsert,?dataFunc);sqlToExecute.Add(Tuple.Create($"{insertSql}{string.Join(",?",?valueSql.Item1)}",?valueSql.Item2));}foreach?(var?sql?in?sqlToExecute){await?connection.ExecuteAsync(sql.Item1,?sql.Item2,?commandTimeout:?int.MaxValue);}}private?static?Tuple<IEnumerable<string>,?DynamicParameters>?GetQueries<T>(IEnumerable<T>?dataToInsert,Dictionary<string,?Func<T,?object>>?dataFunc){var?parameters?=?new?DynamicParameters();return?Tuple.Create(dataToInsert.Select(e?=>?$"({string.Join(",?",?GenerateQueryAndParameters(e,?parameters,?dataFunc))})"),parameters);}private?static?IEnumerable<string>?GenerateQueryAndParameters<T>(T?entity,DynamicParameters?parameters,Dictionary<string,?Func<T,?object>>?dataFunc){var?paramTemplateFunc?=?new?Func<Guid,?string>(guid?=>?$"@p{guid.ToString().Replace("-",?"")}");var?paramList?=?new?List<string>();foreach?(var?key?in?dataFunc){var?paramName?=?paramTemplateFunc(Guid.NewGuid());parameters.Add(paramName,?key.Value(entity));paramList.Add(paramName);}return?paramList;} }

然后可以像下面這樣使用。

await?dbConnection.BulkInsert(?"MySchemaName.MyTableName",?myCollectionOfItems,new?Dictionary<string,?Func<MyObjectToInsert,?object>>{{?"ColumnOne",?u?=>?u.ColumnOne?},{?"ColumnTwo",?u?=>?u.ColumnTwo?},...});

點評區

在實際開發中,批量插入是一個非常常見的場景,用 事務 和 拼sql 都是高效的方式,我在實際開發中,用的是事務方式,學習了。

總結

以上是生活随笔為你收集整理的为什么 Dapper 的批量插入比我预期的要慢很多?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。