用SQLite开发了一个小程序,程序中对数据库的操作利用了C#封装的dataset,datatable,在结束时采用DATAADAPTER.UPDATE写入数据库,结果发现这样操作的数据库执行效率很低,原因是SQLite每一条指令都需要把数据表重新加载,导致大量的IO。解决方法是要把SQL语句封装成一个事务,这样只有一次IO,但是怎么把dataset,datatable的操作转换成SQL语句呢?或者是否还有其它方法,把UPDATE封装成一个事务呢?
代码如下,怎么修改?
using (SQLiteTransaction tran = SQLiteConnection1.BeginTransaction())
{
foreach (DataRow drCurrent in myTables2.Rows)
{
drCurrent2 = mySQLiteTables2.NewRow();
drCurrent2["词组"] = drCurrent["词组"];
drCurrent2["词频"] = stoi(drCurrent["词频"].ToString());
mySQLiteTables2.Rows.Add(drCurrent2);
string cmdInsertText = "insert into 词组表 values(@词组,@词频)";//设置带参SQL语句
this.SQLiteDataAdapter2.InsertCommand = new SQLiteCommand(cmdInsertText,SQLiteConnection1,tran);
this.SQLiteDataAdapter2.InsertCommand.ExecuteNonQuery();
}
tran.Commit();
}
6 个解决方案
你本来就已经“封装成一个事务”了,再说封装成事务就等于是“骑马找马、骑驴找驴“了。并不是你猜的那些东西,而是要去理解的原理。
SQLite我没用过,帮你分析一下吧,为什么要
drCurrent2 = mySQLiteTables2.NewRow();
drCurrent2["词组"] = drCurrent["词组"];
drCurrent2["词频"] = stoi(drCurrent["词频"].ToString());
mySQLiteTables2.Rows.Add(drCurrent2);
多费时间啊!可能SQLite必须这样啊
我的思路:
using (SQLiteTransaction tran = SQLiteConnection1.BeginTransaction())
{
string cmdInsertText = "";
foreach (DataRow drCurrent in myTables2.Rows)
{
string obj1 = drCurrent["词组"].toString();
string obj2 = stoi(drCurrent["词频"].ToString());
mySQLiteTables2.Rows.Add(drCurrent2);
if( cmdInsertText != "" )
{
cmdInsertText += ";";
}
cmdInsertText += "insert into 词组表 values('"+obj1 +"','"+obj2 +"')";//设置带参SQL语句
}
SQLiteCommand cmd = new SQLiteCommand(cmdInsertText,SQLiteConnection1,tran);
cmd .ExecuteNonQuery();
tran.Commit();
}
stoi不懂,思路就是这样,行成一个长长的字符串,当然cmdInsertText长度肯定有限制,65360个字符,够用了。
是不是最优的不敢保证,肯定要比你现在快。我在sql server里就这样设计
对了 ,上面 把 mySQLiteTables2.Rows.Add(drCurrent2);也删除吧