備忘録

備忘録

Dapperの遅いINSERTをDapperPlusを使って高速化する

Ⅰ. はじめに

Dapperで以下のようなINSERTを実行した場合数秒かかります。

var values = Enumerable.Range(0, 10000).Select(x => new { a = x, b = x });
var count = connection.Execute(@"insert MyTable(ColA, ColB) values (@a, @b)", values);

原因はバルクインサートに対応していない為です。
1万回のINSERTを1回1回実行しています。
f:id:kagasu:20180208224806p:plain

残念ながらDapperはバルクインサートに対応していないので、バルクインサートに対応しているDapperPlus(有料)を使います。

Ⅱ. DapperPlusについて

1ヶ月のお試しは無料です。
毎月の初めに最新バージョンをダウンロードすることでお試しの延長ができます。*1
※日付がハードコードされてチェックが行われています。
月に一度このハードコードされた部分が修正されてリリースされます。
つまり、厳密には1ヶ月のお試しではなく各バージョンごとに月末まで使えます。
ダウンロード数を伸ばしたいという作者の意図がありそうです。

if (DateTime.Now < new DateTime(2018, 3, 1)) {
...
}

Ⅲ. DapperPlusの使い方

1. NuGetからZ.Dapper.Plusをインストールする
Install-Package Z.Dapper.Plus
2. サンプルプログラム
using MySql.Data.MySqlClient;
// (NuGet) Install-Package System.ComponentModel.Annotations
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using Z.Dapper.Plus;

[Table("my_table")]
public class Data
{
  [Column("col_a")]
  public int ColA { get; set; }

  [Column("col_b")]
  public int ColB { get; set; }
}

static void Main(string[] args)
{
  var values = Enumerable.Range(0, 10).Select(x => new Data { ColA= x, ColB = x });

  // MySqlConnection は NuGet から MySqlConnector をインストールすると使える
  var conn = new MySqlConnection("userid=user001;password=mypassword;database=mydb;Host=127.0.0.1;charset=utf8");
  conn.Open();

  /*
  // オプションの設定(必須ではない)
  DapperPlusManager
   .Entity<Data>()
   .Table("my_table") // テーブル名を指定する(クラス名とテーブル名が違う場合)
   .BatchSize(100); // バルクインサートを100件づつにする
  */

  // バルクインサートする
  conn.BulkInsert(values);
}
実行結果

f:id:kagasu:20180209003620p:plain