gpt4 book ai didi

c# - DataAdapter.Update() 性能

转载 作者:行者123 更新时间:2023-11-30 16:53:37 24 4
gpt4 key购买 nike

我有一个相对简单的例程,它查看媒体文件的数据库条目,计算宽度、高度和文件大小,然后将它们写回数据库。

数据库是 SQLite,使用 System.Data.SQLite 库,处理大约 4000 行。我将所有行加载到 ADO 表中,用新值更新行/列,然后运行 ​​adapter.Update(table);在上面。

从数据库表加载数据集需要半秒左右,用图像宽度/高度更新所有行并从 FileInfo 获取文件长度大约需要 30 秒。很好。

适配器.Update(table);命令大约需要 5 到 7 分钟才能运行。

这似乎太过分了。 ID 是一个 PK INTEGER,因此——根据 SQLite 的文档,它是固有索引的,但即便如此,我还是忍不住想,如果我为每个单独的更新运行一个单独的更新命令,这会完成得更快。

我曾认为 ADO/适配器是相对较低级别的(与 ORM 相比),这种糟糕的性能让我感到惊讶。谁能阐明为什么需要 5-7 分钟才能针对本地放置的 SQLite 数据库更新一批约 4000 条记录?

顺便说一句,是否有某种方法可以“窥视”ADO 如何处理这个问题?内部库步骤或...??

谢谢

public static int FillMediaSizes() {
// returns the count of records updated

int recordsAffected = 0;

DataTable table = new DataTable();
SQLiteDataAdapter adapter = new SQLiteDataAdapter();

using (SQLiteConnection conn = new SQLiteConnection(Globals.Config.dbAppNameConnectionString))
using (SQLiteCommand cmdSelect = new SQLiteCommand())
using (SQLiteCommand cmdUpdate = new SQLiteCommand()) {

cmdSelect.Connection = conn;
cmdSelect.CommandText =
"SELECT ID, MediaPathCurrent, MediaWidth, MediaHeight, MediaFilesizeBytes " +
"FROM Media " +
"WHERE MediaType = 1 AND (MediaWidth IS NULL OR MediaHeight IS NULL OR MediaFilesizeBytes IS NULL);";

cmdUpdate.Connection = conn;
cmdUpdate.CommandText =
"UPDATE Media SET MediaWidth = @w, MediaHeight = @h, MediaFilesizeBytes = @b WHERE ID = @id;";

cmdUpdate.Parameters.Add("@w", DbType.Int32, 4, "MediaWidth");
cmdUpdate.Parameters.Add("@h", DbType.Int32, 4, "MediaHeight");
cmdUpdate.Parameters.Add("@b", DbType.Int32, 4, "MediaFilesizeBytes");
SQLiteParameter param = cmdUpdate.Parameters.Add("@id", DbType.Int32);
param.SourceColumn = "ID";
param.SourceVersion = DataRowVersion.Original;

adapter.SelectCommand = cmdSelect;
adapter.UpdateCommand = cmdUpdate;

try {
conn.Open();
adapter.Fill(table);
conn.Close();
}
catch (Exception e) {
Core.ExceptionHandler.HandleException(e, true);
throw new DatabaseOperationException("", e);
}

foreach (DataRow row in table.Rows) {

try {

using (System.Drawing.Image img = System.Drawing.Image.FromFile(row["MediaPathCurrent"].ToString())) {

System.IO.FileInfo fi;

fi = new System.IO.FileInfo(row["MediaPathCurrent"].ToString());

if (img != null) {

int width = img.Width;
int height = img.Height;
long length = fi.Length;

row["MediaWidth"] = width;
row["MediaHeight"] = height;
row["MediaFilesizeBytes"] = (int)length;
}
}
}
catch (Exception e) {
Core.ExceptionHandler.HandleException(e);
DevUtil.Print(e);
continue;
}
}


try {
recordsAffected = adapter.Update(table);
}
catch (Exception e) {
Core.ExceptionHandler.HandleException(e);
throw new DatabaseOperationException("", e);
}


}

return recordsAffected;
}

最佳答案

使用 Connection.BeginTransaction() 来加速 DataAdapter 更新。

conn.Open() 'open connection
Dim myTrans As SQLiteTransaction
myTrans = conn.BeginTransaction()
'Associate the transaction with the select command object of the DataAdapter
objDA.SelectCommand.Transaction = myTrans

objDA.Update(objDT)

Try
myTrans.Commit()
Catch ex As Exception
myTrans.Rollback()
End Try
conn.Close()

这大大加快了更新速度。

关于c# - DataAdapter.Update() 性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31287371/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com