提高 sqlite.net 插入时的性能
improve sqlite.net performance at insert
我有要存储在数据库中的记录数。
数据库的模式是这样的
一个人 table 像这样:
CREATE TABLE IF NOT EXISTS Person (id INTEGER PRIMARY KEY, name TEXT)
和这样的文件 table:
CREATE TABLE IF NOT EXISTS File (id INTEGER PRIMARY KEY, FileName TEXT,FilePath TEXT, PersonID NUMERIC CONSTRAINT person_file REFERENCES [Person]([id])ON DELETE NO ACTION ON UPDATE NO ACTION)
我使用这个函数在 tables
中插入
对于 3700 条记录,此代码在我的笔记本电脑上花费了 140 秒,
public long BuildDB(List<DB.Person> persons, List<DB.File> Files, FrmTrain form)
{
long result = -1;
try
{
long personID = 0;
using (SQLiteConnection sqlconnection = new SQLiteConnection("Data Source=" + DbPath + ";Version=3;"))
{
sqlconnection.Open();
SQLiteCommand PersonCommand = sqlconnection.CreateCommand();
SQLiteParameter personParam = new SQLiteParameter();
PersonCommand.CommandText = "INSERT INTO Person('Name') VALUES(?)";
PersonCommand.Parameters.Add(personParam);
SQLiteCommand FileCommand = sqlconnection.CreateCommand();
SQLiteParameter FileParam1 = new SQLiteParameter("@filename");
SQLiteParameter FileParam2 = new SQLiteParameter("@filepath");
SQLiteParameter FileParam3 = new SQLiteParameter("@personid");
FileCommand.CommandText = "INSERT INTO file(FileName,FilePath,PersonID) VALUES(@filename,@filepath,@personid)";
FileCommand.Parameters.Add(FileParam1);
FileCommand.Parameters.Add(FileParam2);
FileCommand.Parameters.Add(FileParam3);
for (int i = 0; i < persons.Count; i++)
{
using (SQLiteTransaction _SQLiteTransaction = sqlconnection.BeginTransaction())
{
personParam.Value = persons[i].Name;
PersonCommand.ExecuteNonQuery();
personID = sqlconnection.LastInsertRowId;
foreach (var item in Files.Where(f => f.PersonID == personID))
{
FileParam1.Value = item.FileName;
FileParam2.Value = item.FilePath;
FileParam3.Value = item.PersonID;
FileCommand.ExecuteNonQuery();
}
_SQLiteTransaction.Commit();
}
form.Progress();
}
sqlconnection.Close();
}
result = 1;
}
catch (Exception e)
{
result = 0;
throw;
}
return result;
}
首先我在没有事务的情况下编写了该代码,它花了大约 500 秒
我试图将第二个 ExecuteNonQuery 包装在一个事务中,但不仅提高了性能,它也花了 500 秒
有没有提高性能的方法?
尝试对所有插入人员使用一个 SQLiteTransaction 和一次提交。
try
{
long personID = 0;
using (SQLiteConnection sqlconnection = new SQLiteConnection("Data Source=" + DbPath + ";Version=3;"))
{
sqlconnection.Open();
SQLiteCommand PersonCommand = sqlconnection.CreateCommand();
SQLiteParameter personParam = new SQLiteParameter();
PersonCommand.CommandText = "INSERT INTO Person('Name') VALUES(?)";
PersonCommand.Parameters.Add(personParam);
SQLiteCommand FileCommand = sqlconnection.CreateCommand();
SQLiteParameter FileParam1 = new SQLiteParameter("@filename");
SQLiteParameter FileParam2 = new SQLiteParameter("@filepath");
SQLiteParameter FileParam3 = new SQLiteParameter("@personid");
FileCommand.CommandText = "INSERT INTO file(FileName,FilePath,PersonID) VALUES(@filename,@filepath,@personid)";
FileCommand.Parameters.Add(FileParam1);
FileCommand.Parameters.Add(FileParam2);
FileCommand.Parameters.Add(FileParam3);
using (SQLiteTransaction _SQLiteTransaction = sqlconnection.BeginTransaction())
{
for (int i = 0; i < persons.Count; i++)
{
personParam.Value = persons[i].Name;
PersonCommand.ExecuteNonQuery();
personID = sqlconnection.LastInsertRowId;
foreach (var item in Files.Where(f => f.PersonID == personID))
{
FileParam1.Value = item.FileName;
FileParam2.Value = item.FilePath;
FileParam3.Value = item.PersonID;
FileCommand.ExecuteNonQuery();
}
}
_SQLiteTransaction.Commit();
form.Progress();
}
sqlconnection.Close();
}
result = 1;
}
catch (Exception e)
{
result = 0;
throw;
}
我有要存储在数据库中的记录数。
数据库的模式是这样的
一个人 table 像这样:
CREATE TABLE IF NOT EXISTS Person (id INTEGER PRIMARY KEY, name TEXT)
和这样的文件 table:
CREATE TABLE IF NOT EXISTS File (id INTEGER PRIMARY KEY, FileName TEXT,FilePath TEXT, PersonID NUMERIC CONSTRAINT person_file REFERENCES [Person]([id])ON DELETE NO ACTION ON UPDATE NO ACTION)
我使用这个函数在 tables
对于 3700 条记录,此代码在我的笔记本电脑上花费了 140 秒,
public long BuildDB(List<DB.Person> persons, List<DB.File> Files, FrmTrain form)
{
long result = -1;
try
{
long personID = 0;
using (SQLiteConnection sqlconnection = new SQLiteConnection("Data Source=" + DbPath + ";Version=3;"))
{
sqlconnection.Open();
SQLiteCommand PersonCommand = sqlconnection.CreateCommand();
SQLiteParameter personParam = new SQLiteParameter();
PersonCommand.CommandText = "INSERT INTO Person('Name') VALUES(?)";
PersonCommand.Parameters.Add(personParam);
SQLiteCommand FileCommand = sqlconnection.CreateCommand();
SQLiteParameter FileParam1 = new SQLiteParameter("@filename");
SQLiteParameter FileParam2 = new SQLiteParameter("@filepath");
SQLiteParameter FileParam3 = new SQLiteParameter("@personid");
FileCommand.CommandText = "INSERT INTO file(FileName,FilePath,PersonID) VALUES(@filename,@filepath,@personid)";
FileCommand.Parameters.Add(FileParam1);
FileCommand.Parameters.Add(FileParam2);
FileCommand.Parameters.Add(FileParam3);
for (int i = 0; i < persons.Count; i++)
{
using (SQLiteTransaction _SQLiteTransaction = sqlconnection.BeginTransaction())
{
personParam.Value = persons[i].Name;
PersonCommand.ExecuteNonQuery();
personID = sqlconnection.LastInsertRowId;
foreach (var item in Files.Where(f => f.PersonID == personID))
{
FileParam1.Value = item.FileName;
FileParam2.Value = item.FilePath;
FileParam3.Value = item.PersonID;
FileCommand.ExecuteNonQuery();
}
_SQLiteTransaction.Commit();
}
form.Progress();
}
sqlconnection.Close();
}
result = 1;
}
catch (Exception e)
{
result = 0;
throw;
}
return result;
}
首先我在没有事务的情况下编写了该代码,它花了大约 500 秒 我试图将第二个 ExecuteNonQuery 包装在一个事务中,但不仅提高了性能,它也花了 500 秒
有没有提高性能的方法?
尝试对所有插入人员使用一个 SQLiteTransaction 和一次提交。
try
{
long personID = 0;
using (SQLiteConnection sqlconnection = new SQLiteConnection("Data Source=" + DbPath + ";Version=3;"))
{
sqlconnection.Open();
SQLiteCommand PersonCommand = sqlconnection.CreateCommand();
SQLiteParameter personParam = new SQLiteParameter();
PersonCommand.CommandText = "INSERT INTO Person('Name') VALUES(?)";
PersonCommand.Parameters.Add(personParam);
SQLiteCommand FileCommand = sqlconnection.CreateCommand();
SQLiteParameter FileParam1 = new SQLiteParameter("@filename");
SQLiteParameter FileParam2 = new SQLiteParameter("@filepath");
SQLiteParameter FileParam3 = new SQLiteParameter("@personid");
FileCommand.CommandText = "INSERT INTO file(FileName,FilePath,PersonID) VALUES(@filename,@filepath,@personid)";
FileCommand.Parameters.Add(FileParam1);
FileCommand.Parameters.Add(FileParam2);
FileCommand.Parameters.Add(FileParam3);
using (SQLiteTransaction _SQLiteTransaction = sqlconnection.BeginTransaction())
{
for (int i = 0; i < persons.Count; i++)
{
personParam.Value = persons[i].Name;
PersonCommand.ExecuteNonQuery();
personID = sqlconnection.LastInsertRowId;
foreach (var item in Files.Where(f => f.PersonID == personID))
{
FileParam1.Value = item.FileName;
FileParam2.Value = item.FilePath;
FileParam3.Value = item.PersonID;
FileCommand.ExecuteNonQuery();
}
}
_SQLiteTransaction.Commit();
form.Progress();
}
sqlconnection.Close();
}
result = 1;
}
catch (Exception e)
{
result = 0;
throw;
}