0

100万行半を超える.DBFファイル(同じ構造の6つのDBFファイル)があります。また、作成したAPIを使用してこのデータをSQLデータベースに移行するC#アプリもあります。

プログラムはすぐに起動し、1秒間に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です。

4

3 に答える 3

1

Rushmoreを実行しているクエリは最適化されていますか?つまり、フィールドNOTEPOINTおよびNOTEDESCのテーブルにインデックスがありますか?

于 2012-07-20T08:38:46.473 に答える
0

DataReaderの代わりにを使用するようにコードを変換しますDataTable。ループを使用しwhileて結果を繰り返します。foreachのループDataTableも物事を遅​​くしていると思います。値の読み取りのみを順方向に実行しているため、これによりパフォーマンスが向上します。

詳細、特にセクションについては、パフォーマンスの比較:データアクセス手法を参照してください。DataReader vs. DataSet

DataReaderは、最適化された読み取り専用および転送専用のデータアクセスを必要とするアプリケーションに適しています。DataReaderからデータをロードし、DataReaderを閉じ、データベース接続を閉じるのが早ければ早いほど、パフォーマンスが向上します。DataReaderは、アプリケーションがデータを読み取る間、他の目的には使用できないデータベース接続を保持するため、アプリケーションが競合が発生するのに十分な時間DataReaderを保持すると、スケーラビリティが制限される可能性があります。DataSetは、データが入力されている間だけ接続を保持する必要があります。いっぱいになると、接続が閉じられてプールに戻される場合があります。接続がすでにプールに戻されている可能性があるため、DataSetからのデータの読み取りを遅らせても、競合は発生しません。

于 2012-07-20T14:40:51.503 に答える
0

問題は、SQL側のテーブルでのデータベーストリガーでした。操作中にそれらを無効にすると(この場合は必要ありません)、問題は解決しました。

于 2012-07-25T22:13:58.727 に答える