0
  public DataTable FetchData(string sQuery)
  {
    DataTable dtable = new DataTable();           

   using (SqlConnection conn = new SqlConnection(conString))
   {
      conn.Open();

      using (SqlCommand sqlCmd = new SqlCommand(sQuery, conn))
      {
        SqlDataReader sdRead = sqlCmd.ExecuteReader();
        dtable.Load(sdRead);
      }
    }

return dtable;
}


 Datatable dt = FetchData(string sQuery);
 foreach(DataRow row in table.Rows)
  ClassA obj = new ClassA(row);

 // Some manipulations
  //.....

Class A
{

  int id;
  int name;

 A(DataRow dr)
 {

  id = dr["ID"];
  name = dr["Name"];

}
}

データベースから約 15,00,000 行を取得する必要があります。

2 つのシナリオについて提案が必要です。

  1. 上記のメソッドを 1 ~ 5 回呼び出すので、明らかに 1 ~ 5 個の接続が作成されます。wtの10~20倍になれば性能は?(または、1 つのグローバル接続を作成し、1 つの接続を開いてすべてを処理し、最後に閉じます。)

  2. データテーブルはどうですか?任意の代替。これほど多くの行には、ここで切断されたアーキテクチャが必要だと思います。取得したデータを自分のクラス オブジェクトに詰め込む必要があります (または、datareader をList<objects>繰り返し、FetchData() の中に詰め込みます)。

助言がありますか?

4

1 に答える 1

3

最初に、データベース内でできるだけ多くのものを前処理することを試みることができます (それが得意です)。

次に、取得するデータを縮小し、操作を並列化する必要があります。ここでいくつかの問題を説明しましょう。

  1. 1 つのネットワーク パイプを介して大量のデータを読み込もうとする場合
  2. 次に、膨大な量のデータをすべてメインメモリに保存しようとします
  3. 次に、すべてをロードして割り当てた後、データに対していくつかの計算を行います

より簡単な手順の 1 つは、データを小さなセット (200 行程度)に分割することです。次に、多くのスレッドを並行して実行し(スレッドごとに1つの接続)、すべてのスレッドが少量の行をフェッチし、それらをメモリに入れ、必要なものを計算します(次に、に比例する未使用のメモリを解放しますnumber_of_workers x rows_loaded_by_worker)。

次に、フェッチされた行数 (100 ~ 10000) と並列ワーカーの数を調整して、プロセスを微調整します。

SQL クエリは、多数の小さなデータ セットを取得するために効率的である必要があることに注意してください (つまりEXPLAIN、テーブル スキャンが含まれていないことを確認するために を使用します。そうしないと、そのようなアプローチは失敗します)。

于 2012-06-09T11:57:15.230 に答える