Visual FoxPro OLE DB性能问题循环DBF文件

时间:2012-07-19 15:40:59

标签: c# .net foxpro visual-foxpro

我有一个.DBF文件(嗯,6个DBF文件具有相同的结构),有超过一百五十行。我还有一个C#应用程序,它使用我们制作的API将这些数据迁移到SQL数据库中。

程序启动很快,能够每秒处理30或40行,但随着时间的推移逐渐减慢,我不知道为什么。我相信我的处理速度很快。

我在vfpoledb中使用的连接字符串是

"Provider=vfpoledb;Data Source=" + sourceDBFolder + ";Collating Sequence=machine;MVCOUNT=32000;ENGINEBEHAVIOR=90;TABLEVALIDATE=0;REFRESH=0";

sourceDBFolder是磁盘上的路径。我还在开始任务之前执行以下代码:

System.Data.OleDb.OleDbCommand oRefreshCommand = oConn.CreateCommand();
oRefreshCommand.CommandText = "EXECSCRIPT([SET REFRESH TO 0,0])";
oRefreshCommand.ExecuteNonQuery();

这是相关代码。如果未按下面的顺序放置,则select语句中的where子句将导致瓶颈。

string[] noteTables = new string[] { "note1", "note2", "note3", "note4", "note5", "note6" };
foreach (long lNoteKey in oCaseLookupTable.Keys) {
  for (int y = 0; y <= 5; y++) {
    System.Data.OleDb.OleDbCommand oNotesCmd = oConn.CreateCommand();
    oNotesCmd.CommandText = "SELECT NOTEDATE, NOTEDESC, ENTEREDBY FROM " + noteTables[y] + " WHERE NOTEPOINT = " + lNoteKey.ToString() + " AND NOTEDESC NOT LIKE 'Folder accessed%'";
    DataTable oNotesTable = new DataTable();
    oNotesTable.Load(oNotesCmd.ExecuteReader());
    foreach (DataRow oRow in oNotesTable.Rows) { 
      //Do processing on rows, Note is my created class.
      Note oNote = new Note();
      oNote.NoteValue = oRow["NOTEDESC"].ToString().Trim();
      oNote.ReferenceID = oCaseLookupTable[lNoteKey];
      DateTime createdDate;
      if (DateTime.TryParse(oRow["NOTEDATE"].ToString().Trim(), out createdDate))
        oNote.CreatedDate = createdDate;
      else
        oNote.CreatedDate = DateTime.Now;
      Result oNoteResult = oNote.Insert();
    }
    oNotesTable.Dispose();
    oNotesCmd.Dispose();
  }
}

简单地说,我不明白为什么这会逐渐变慢和变慢。 PerfMon不会显示任何随时间推移的托管内存块。我尝试通过连续调用DBF文件来保持我的DataTable小。通常,从查询返回的最大行数为1,000。

3 个答案:

答案 0 :(得分:1)

您正在执行Rushmore的查询是否已经优化,即表中是否存在NOTEPOINT和NOTEDESC字段的索引?

答案 1 :(得分:0)

转换代码以使用DataReader而不是DataTable。使用while循环迭代结果。我相信foreach上的DataTable循环也会减慢速度。由于您只是向前阅读值,这将为您带来性能提升:

有关详情,请参阅Performance Comparison: Data Access Techniques,尤其是DataReader vs. DataSet

部分
  

对于需要的应用程序,DataReader是更好的选择   优化的只读和仅向前数据访问。你越早装载   关闭DataReader的数据,关闭DataReader,然后关闭   数据库连接,您获得的性能会更好。因为   DataReader拥有一个不能用于任何数据库的数据库连接   应用程序读取数据时的其他目的,可能会限制   如果应用程序持有DataReader足够长的可扩展性   争用发生。 DataSet只需要保持连接   它正在填充。填充后,可以关闭连接   并返回游泳池。延迟从DataSet读取数据   不会引起争用,因为连接可能已经发生   已经回到了游泳池。

答案 2 :(得分:0)

问题是SQL端的表上有一些数据库触发器。在操作期间禁用它们(在这种情况下不需要它们)解决了这个问题。