noxi雑記

.NET、Angularまわりの小ネタブログ

C#でデータベースに行を追加するパフォーマンスを測定してみた

最近コンソールアプリで C# から SQLServer にデータのバッチ投入・更新・削除を試しています。単純な SQL の実行はいつも Dapper を利用しているのですが思うような実行結果にならなかったため、何種類かの方法でデータの一括投入のパフォーマンス計測してみました。



測定方法

今回は .NET Core 3.1 で作った簡単なプログラムを Azure Functions 上で実行し、データ挿入のパフォーマンスを測定します。
測定対象は Dapper 、 EntityFramework Core 、および SqlBulkCopy です。適当なデータを千件、1万件一括挿入してみます。それぞれ10回実行し、最初の1回を除いた9回の平均値を取ります。

使用したソースコードこちら

環境

  • Runtime/Libs
    • Dapper@2.0.35
    • Microsoft.NET.Sdk.Functions@3.0.6
    • Microsoft.Data.SqlClient@1.1.2
    • EntityFramework Core@3.1.3
  • Azure Resources (West US 2)
    • Azure Functions (.NET Core 3.1 / AppService Plan S1)
    • Azure SQL Database (S3 / DTU 100)

結果

一括挿入するなら BulkCopy 一択です。超高速で他を寄せ付けません。
Dapper は BulkInsert 機能がデフォルトでは存在せず、件数分の INSERT を実行します。つらい。
EFCore はデフォルトだと500件?を一括挿入するためパフォーマンスは良い、、、と見せかけ、オブジェクト管理に関する処理が重すぎて結局 Dapper に近い時間かかります。もっとも、今回は一括で SaveChanges を呼び出していますので分割すればもう少しパフォーマンスの向上は狙えるかもしれません。

以下、測定結果。

f:id:noxi515:20200503035927p:plain
測定結果(単位:ms)

種類 回数 平均
Dapper 1000 918 1345 949 975 933 848 896 910 915 901 939
EFCore 1000 751 2867 796 752 781 730 726 748 735 734 759
BulkCopy 1000 21 312 21 21 25 20 22 21 21 17 22
Dapper 10000 8273 10003 9196 8076 7975 7976 7819 8099 9436 8033 7844
EFCore 10000 7588 9715 7994 7525 7430 7618 7593 7558 7598 7502 7473
BulkCopy 10000 387 136 373 626 354 346 357 364 361 361 340