SQLiteトランザクションSQLite複数の文を挿入するのはなぜこんなに遅いのですか.のnet (C#)
8016 ワード
今日ある友达はSQLiteをテストして、それから結論を出しました:SQLiteの効率が低すぎて、大量に1000本の記録を挿入して、意外にも2分かかります!次は彼が送ってくれたテストコードです.めまいがする~~~~~
あ~~~~~~~常識的なエラーで、コードを何行か追加しました(新しいコードタグ「//<------------------------」).
実行に0.2秒かかります.この差は大きすぎるのではないでしょうか.なぜ単純にトランザクションを有効にするだけでこんなに大きな差があるのでしょうか.簡単です.SQLiteはデフォルトで各操作ごとに1つのトランザクションを開始します.元のコードを1000回挿入すると、少なくとも1000のトランザクションがオープンします.「トランザクションオープン+SQL実行+トランザクションクローズ」は自然に多くの時間を費やします.これも、トランザクションの開始後になぜこんなに速いのかを示す原因です.実はこれはデータベースの操作の基本的な常識で、みんなは覚えていて、悪いコードの効率が悪いのは少し半ではありません.
using System.Data;
using System.Data.Common;
using System.Data.SQLite;
//
File.Delete("test1.db3");
SQLiteConnection.CreateFile("test1.db3");
DbProviderFactory factory = SQLiteFactory.Instance;
using (DbConnection conn = factory.CreateConnection())
{
//
conn.ConnectionString = "Data Source=test1.db3";
conn.Open();
//
string sql = "create table [test1] ([id] INTEGER PRIMARY KEY, [s] TEXT COLLATE NOCASE)";
DbCommand cmd = conn.CreateCommand();
cmd.Connection = conn;
cmd.CommandText = sql;
cmd.ExecuteNonQuery();
//
cmd.Parameters.Add(cmd.CreateParameter());
//
Stopwatch watch = new Stopwatch();
watch.Start();
// 1000
for (int i = 0; i < 1000; i++)
{
cmd.CommandText = "insert into [test1] ([s]) values (?)";
cmd.Parameters[0].Value = i.ToString();
cmd.ExecuteNonQuery();
}
//
watch.Stop();
Console.WriteLine(watch.Elapsed);
}
あ~~~~~~~常識的なエラーで、コードを何行か追加しました(新しいコードタグ「//<------------------------」).
using System.Data;
using System.Data.Common;
using System.Data.SQLite;
//
File.Delete("test1.db3");
SQLiteConnection.CreateFile("test1.db3");
DbProviderFactory factory = SQLiteFactory.Instance;
using (DbConnection conn = factory.CreateConnection())
{
//
conn.ConnectionString = "Data Source=test1.db3";
conn.Open();
//
string sql = "create table [test1] ([id] INTEGER PRIMARY KEY, [s] TEXT COLLATE NOCASE)";
DbCommand cmd = conn.CreateCommand();
cmd.Connection = conn;
cmd.CommandText = sql;
cmd.ExecuteNonQuery();
//
cmd.Parameters.Add(cmd.CreateParameter());
//
Stopwatch watch = new Stopwatch();
watch.Start();
DbTransaction trans = conn.BeginTransaction(); // <-------------------
try
{
// 1000
for (int i = 0; i < 1000; i++)
{
cmd.CommandText = "insert into [test1] ([s]) values (?)";
cmd.Parameters[0].Value = i.ToString();
cmd.ExecuteNonQuery();
}
trans.Commit(); // <-------------------
}
catch
{
trans.Rollback(); // <-------------------
throw; // <-------------------
}
//
watch.Stop();
Console.WriteLine(watch.Elapsed);
}
実行に0.2秒かかります.この差は大きすぎるのではないでしょうか.なぜ単純にトランザクションを有効にするだけでこんなに大きな差があるのでしょうか.簡単です.SQLiteはデフォルトで各操作ごとに1つのトランザクションを開始します.元のコードを1000回挿入すると、少なくとも1000のトランザクションがオープンします.「トランザクションオープン+SQL実行+トランザクションクローズ」は自然に多くの時間を費やします.これも、トランザクションの開始後になぜこんなに速いのかを示す原因です.実はこれはデータベースの操作の基本的な常識で、みんなは覚えていて、悪いコードの効率が悪いのは少し半ではありません.