【发布时间】:2012-07-19 15:40:59
【问题描述】:
我有一个超过一百万行的 .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 很小。一般来说,查询返回的最大行数是 1000。
【问题讨论】:
-
你为什么不通过一个选择来做到这一点,例如:WHERE (NOTEPOINT = 'note1' or NOTEPOINT = 'note2'....) AND NOTEDESC NOT LIKE ...
-
好吧,oCaseLookupTable.Keys 集合中有大约 6300 个值。我想我可以只为每个表使用一个选择,抓取该表中的所有行,如果我在我的 Keys 集合中找不到匹配项,则跳过该行,但我以前这样做过,它同样慢.
-
ONote.Insert 是做什么的?似乎插入中可能发生了导致速度变慢的事情。是否有一些查询运行时间越长,越多的记录放入 SQL 表中?
-
oNote.Insert 创建一个新的 SqlConnection 和 SqlCommand,并执行 SqlCommand.ExecuteScalar。命令本身由两部分组成:一个包含大约 10 列的基本插入语句,然后调用 SELECT SCOPE_IDENTITY() 以获取我们刚刚输入的 Note 的 ID 值(在这种情况下实际上不需要,所以如果这是导致减速的主要原因,则可以将其删除)
-
我看不到任何地方 SELECT SCOPE_IDENTITY 会随着时间的推移导致性能大幅下降,但假设您插入了 500,000 行,并且每次都调用它。它会让每个后续调用变得越来越慢吗?
标签: c# .net foxpro visual-foxpro