下午大家。我不熟悉SQLite,所以我沒有搞砸數據庫的所有設置。我對SQL Server,Oracle甚至一些Access和mySQL非常熟悉。那麼,目前,我正在接收一個包含110,000多條記錄的文件,並逐行讀取文件,解析數據並在表中插入一條語句。該表取決於第一行的記錄類型。那麼,我現在正在加載它,它已經運行了12分鐘(正如我寫的那樣),並且只導入了14,000條記錄。進行數學計算,這意味着它需要1小時15分鐘到1小時30分鐘之間的時間。取決於我的系統其餘部分當時的行爲。由於存在不同的記錄類型,因此如果有SQLite選項(不確定是否存在),則無法進行批量插入。這是作爲後臺工作人員運行的。下面是拉取和分析數據的函數,以及將其插入數據庫的函數。請記住,這是MVC格式的C#應用程序(就像當我控制了它,並沒有足夠的時間來重組它):有沒有更快的方式來讀取文件並插入到SQLite中
MainForm.cs後臺輔助功能
#region Background Worker Functions
#region private void InitializeBackgroundWorker()
/*************************************************************************************
*************************************************************************************/
private void InitializeBackgroundWorker()
{
backgroundWorker.DoWork +=
new DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker.RunWorkerCompleted +=
new RunWorkerCompletedEventHandler(
backgroundWorker1_RunWorkerCompleted);
backgroundWorker.ProgressChanged +=
new ProgressChangedEventHandler(
backgroundWorker1_ProgressChanged);
}
#endregion
/*****************************************************************************************************************************************************************************************************/
#region private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
/*************************************************************************************
*************************************************************************************/
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
// Get the BackgroundWorker that raised this event.
BackgroundWorker worker = sender as BackgroundWorker;
// Assign the result of the computation
// to the Result property of the DoWorkEventArgs
// object. This is will be available to the
// RunWorkerCompleted eventhandler.
//Creates a static singleton file list. Remains on the stack and can be accessed anywhere without
// reinstatiating
object[] obj = (object[])e.Argument;
string fileName = obj[0].ToString();
DataController controller = new DataController(worker, e);
controller.FileName = fileName;
try
{
if (strProcess == "Import")
{
controller.Import();
}
else if (strProcess == "Export")
{
controller.ExportToExcel();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
}
}
#endregion
/*****************************************************************************************************************************************************************************************************/
#region private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
/*************************************************************************************
*************************************************************************************/
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
MessageBox.Show(e.Error.StackTrace);
}
else
{
this.toolStripStatusLabel1.Text = "Import complete";
generateReport();
treeViewFigure.Nodes.Clear();
BuildTree();
treeViewFigure.TopNode.ExpandAll();
labelIPBNumber.Text = controller.IPBNumber;
this.Text += "IPB: " + labelIPBNumber.Text;
cmbIndentureLevel.Items.Clear();
}
}
#endregion
/*****************************************************************************************************************************************************************************************************/
#region private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
/*************************************************************************************
*************************************************************************************/
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
string stat = e.UserState.ToString();
this.toolStripStatusLabel1.Text = "";
this.toolStripStatusLabel1.Text = stat;
this.toolStripProgressBar1.Value = e.ProgressPercentage;
}
#endregion
#endregion
Importer.cs導入功能
#region public void Import(string fileName)
/*************************************************************************************
*************************************************************************************/
public void Import(string fileName)
{
if (!File.Exists(fileName))
{
throw new FileNotFoundException();
}
StreamReader read = File.OpenText(fileName);
List<RecordBase> List = new List<RecordBase>();
DataFactory factory = DataFactory.BuildFactory();
int nLines = 0;
while (!read.EndOfStream)
{
read.ReadLine();
nLines++;
}
read.Close();
read = File.OpenText(fileName);
factory.lstObservers = _observers;
factory.ClearDB();
int count = 1;
while (!read.EndOfStream)
{
string[] fields = read.ReadLine().Split('|');
List<string> lstStr = new List<string>();
foreach (string str in fields)
{
lstStr.Add(str);
}
lstStr.RemoveAt(fields.Length - 1);
fields = lstStr.ToArray();
string strValues = string.Join("','", fields);
strValues = "'" + strValues + "'";
if (fields.Length >= 39 && fields[0] == "03")
{
factory.ImportTaggedRecord(fields[38], count);
int nIndex = strValues.IndexOf(fields[38]);
strValues = strValues.Substring(0, nIndex - 2);
}
factory.ImportIPB(strValues, fields[0], count);
progress.ProgressComplete = (count * 100)/nLines;
progress.Message = "Importing Record: " + count++.ToString();
Notify();
}
}
#endregion
DataFactory.cs ImportIPB功能
#region public void ImportIPB(string strValues, string strType)
/*************************************************************************************
*************************************************************************************/
public void ImportIPB(string strValues, string strType, int nPosition)
{
string strCommand = string.Empty;
switch (strType)
{
case "01":
strCommand = Queries.strIPBInsert;
break;
case "02":
strCommand = Queries.strFigureInsert;
break;
case "03":
strCommand = Queries.strPartInsert;
break;
}
ExecuteNonQuery(strCommand + strValues + ", " + nPosition.ToString() + ")");
}
#endregion
Database.cs ExecuteNonQuery方法
#region public void ExecuteNonQuery(string strSQL)
/*************************************************************************************
*************************************************************************************/
public void ExecuteNonQuery(string strSQL)
{
DbCommand dbCommand = _dbConnection.CreateCommand();
dbCommand.CommandText = strSQL;
dbCommand.Prepare();
dbCommand.ExecuteNonQuery();
}
#endregion
任何人都可以看到提供的任何東西可以改進嗎?是否有設置可以設置爲更快工作的後臺工作人員?是否有後臺工作人員的默認設置?數據庫文件上有哪些可以更改的設置(使用SQLite專用個人版)以使插入更快?它只是我的文件的大小?現在,當我完成這個時候,它剛剛過去了22分鐘,它完成了24,000條記錄。這不是一個時間敏感的問題,所以你需要時間。謝謝。
更新:另外,我想我應該提到在其中一個表中我有一個整數主鍵(作爲標識字段)。可以有任何性能問題嗎?
好的,我會研究一下。 – XstreamINsanity 2010-08-31 18:21:34
現在我必須找出實現它的最佳方式,因爲我在一個文件中建立了連接,並且將插入逐一創建到另一個文件中。我有可能在我的數據庫文件中創建一個BeginTransaction函數,在我開始讀取文件之前調用它,然後在我的數據庫文件中創建一個Commit函數並在讀完文件後調用它?或者那會不理想? – XstreamINsanity 2010-08-31 18:30:24
我認爲這很好。 'BeginTransaction'返回'DbTransaction',所以你可以將它存儲在'Database'實例字段中,然後在完成時調用'Commit'。 – 2010-08-31 18:36:25