[英]Take too long time to write in to Access Data Base using C# WPF application, Visual Studio,
我有一個使用C#和VS的WPF應用程序。 我正在使用Access數據庫。 我有一個循環,最長要運行500MS,但是要花570 +-
在我的程序中,我總共有〜340MS的等待時間,還有超過160MS的等待時間可以優化
在用秒表檢查后,我發現當我將數據寫入Access數據庫時,它需要大約50MS(我有3次寫入)。 我不知道如何優化我的數據庫寫入
連接和使用數據庫的我的類是一個看起來像這樣的外部DLL文件(我還給出了一個采用50MS運行時的方法示例,命名為“AddDataToLocalHeaderResult”):
namespace DataBaseManager
{
public class LocalPulserDBManager
{
private string localConnectionString;
private string databaseName = $@"C:\Pulser\LocalPulserDB.mdb";
private readonly int _30DaysBack = -30;
private static readonly Lazy<LocalPulserDBManager> lazy =new Lazy<LocalPulserDBManager>(() => new LocalPulserDBManager());
public static LocalPulserDBManager LocalPulserDBManagerInstance { get { return lazy.Value; } }
private void CreateConnectionString()
{
localConnectionString = $@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={databaseName};Persist Security Info=True";
}
private LocalPulserDBManager()
{
CreateConnectionString();
}
public void AddDataToLocalHeaderResult(string reportNumber,string reportDescription,
string catalog,string workerName,int machineNumber, Calibration c,string age)
{
if (IsHeaderLocalDataExist(reportNumber, catalog, machineNumber, c) == false)
{
using (OleDbConnection openCon = new OleDbConnection(localConnectionString))
{
string query = "INSERT into [HeaderResult] ([ReportNumber],[ReportDescription],[CatalogNumber], " +
"[WorkerName], [LastCalibrationDate], [NextCalibrationDate], [MachineNumber], [Age]) " +
"VALUES (@report ,@reportDescription ,@catalog, @workerName," +
" @LastCalibrationDate, @NextCalibrationDate, @machineNumber, @age)";
using (OleDbCommand command = new OleDbCommand(query))
{
command.Parameters.AddWithValue("@report", reportNumber);
command.Parameters.AddWithValue("@reportDescription", reportDescription);
command.Parameters.AddWithValue("@catalog", catalog);
command.Parameters.AddWithValue("@workerName", workerName);
command.Parameters.AddWithValue("@LastCalibrationDate", c.LastCalibrationDate);
command.Parameters.AddWithValue("@NextCalibrationDate", c.NextCalibrationDate);
command.Parameters.AddWithValue("@machineNumber", machineNumber);
command.Parameters.AddWithValue("@age", age);
command.Connection = openCon;
openCon.Open();
int recordsAffected = command.ExecuteNonQuery();
openCon.Close();
}
}
}
}
....
....
METHODS
....
}
}
在我的可執行程序中,我使用它:
我有這樣的用法: using static DataBaseManager.LocalPulserDBManager;
在我的代碼中,我執行像LocalPulserDBManagerInstance.AddDataToLocalHeaderResult(ReportNumber, Date_Description,CatalogNumber, WorkerName, (int)MachineNumber, calibrationForSave, AgeCells);
50MS在那種情況下是正常的運行時間嗎? 如果這里缺少任何信息請告訴我......
*********************編輯**************************
我已經更改了我的AddDataToLocalHeaderResult
方法,因為第一個命令告訴我我得到了相同的結果
public void AddDataToLocalHeaderResult(string reportNumber,string reportDescription,
string catalog,string workerName,int machineNumber, Calibration c,string age)
{
if (IsHeaderLocalDataExist(reportNumber, catalog, machineNumber, c) == false)
{
using (OleDbConnection openCon = new OleDbConnection(localConnectionString))
{
string query = "INSERT into [HeaderResult] ([ReportNumber],[ReportDescription],[CatalogNumber], " +
"[WorkerName], [LastCalibrationDate], [NextCalibrationDate], [MachineNumber], [EditTime], [Age]) " +
"VALUES (@report ,@reportDescription ,@catalog, @workerName," +
" @LastCalibrationDate, @NextCalibrationDate, @machineNumber,@edittime, @age)";
DateTime dt = DateTime.Now;
DateTime edittime = new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second);
using (OleDbCommand command = new OleDbCommand(query))
{
command.Parameters.AddWithValue("@report", reportNumber);
command.Parameters.AddWithValue("@reportDescription", reportDescription);
command.Parameters.AddWithValue("@catalog", catalog);
command.Parameters.AddWithValue("@workerName", workerName);
command.Parameters.AddWithValue("@LastCalibrationDate", c.LastCalibrationDate);
command.Parameters.AddWithValue("@NextCalibrationDate", c.NextCalibrationDate);
command.Parameters.AddWithValue("@machineNumber", machineNumber);
command.Parameters.AddWithValue("@edittime", edittime);
command.Parameters.AddWithValue("@age", age);
command.Connection = openCon;
openCon.Open();
int recordsAffected = command.ExecuteNonQuery();
openCon.Close();
}
}
}
}
使用此處顯示的方法,您一次要添加一行。 因此,服務器正在打開與數據庫的連接,將數據寫入內存,然后再寫入物理文件(mdb),然后更新索引。 這是你要嘗試執行的每行完整的四個步驟。 更糟糕的是,將數據寫入物理文件非常耗時。
我認為如果您使用其他方法,請對要插入的整個數據集執行這四個步驟(連接,內存,數據寫入,重新索引)。 因此,假設您要添加1000條記錄,而不是4000個步驟(4x1000),則可以將該處理減少到1400個處理步驟(1個連接,超快的1000個內存寫入,1個數據文件寫入,1個索引修訂)。
下面的代碼粗略地概括了我在說什么:
class Program
{
static void Main(string[] args)
{
//memory-only list for data loading
List<HeaderResult> mylist = new List<HeaderResult>(){ new HeaderResult("report1","desc of report","ete"), new HeaderResult("report2", "desc of report2", "ete2")};
var tableForInsert = new DataTable();
using (SqlDataAdapter dataAdapter = new SqlDataAdapter("SELECT * from HeaderResult", "my conneciton string")) {
dataAdapter.Fill(tableForInsert);
//now I have a live copy of the table into which I want to insert data
//blast in the data
foreach (HeaderResult hr in mylist) {
tableForInsert.Rows.Add(hr);
}
//now all the data is written at once and sql will take care of the indexes after the datat's written
dataAdapter.Update(tableForInsert);
}
}
//class should have same fields as your table
class HeaderResult
{
string report;
string reportDescription;
string etc;
public HeaderResult(string rpt, string desc, string e)
{
report = rpt;
reportDescription = desc;
etc = e;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.