0

ネットワークにpostgreサーバーがあり、データベースを使用しています。大量のレコード(1mil以上)を調べる必要があり、各選択には時間がかかります。

これは私の現在の方法です:

DataSet ds = new psqlWork().getDataSet("SELECT * FROM z_sitemap_links"); 
DataTable dt = ds.Tables[0]; 
Parallel.ForEach(dt.AsEnumerable(), dr => 
{ 
    new Sitemap().runSitemap(dr[1].ToString(), counter); 
    counter++; 
}); 

しかし、DBサイズが大きくなると、この方法は(私の意見では)それほど効果的ではなくなります。これを行うためのより良い方法を提案できますか?たぶん、データをプルしてチャンクで処理します。今はこれをどうやって管理するのかわかりませんが。

4

1 に答える 1

8

最適化のポイント:

  • DataSet名前付きの型を作成し、 andを使用する代わりに、ADO.NET を使用して名前付きの型に読み込みますDataTable。これにより、メモリ フットプリントの一部が削減されます。
  • 実際に作業する必要があるレコードのみをプルします (100 万を超えるレコードを取り込む必要はあまりありませんが、ビジネス ロジックはわかりません)。

元の投稿を明確にするための質問:

  • これが将来拡張されない理由はありますか?
  • を利用していることをどのように処理していますParallel.ForEachか?基礎となるシステムにその能力がある場合、おそらく現在のアプローチで問題ないでしょう。また、何が起こるかを単に推測するのではなく、実際のパフォーマンスをプロファイリングする必要があることも考慮してください。
DataSet ds = new psqlWork().getDataSet(@"
  SELECT * FROM z_sitemap_links 
  order by timestamp asc /*always order when skipping records so you get the same skips */
  LIMIT 100000 /* using these two with variables you could skip so many records /*
  OFFSET 100000 /* depending on what you're aiming for */
"); 
DataTable dt = ds.Tables[0]; 
Parallel.ForEach(dt.AsEnumerable(), dr => 
{ 
    new Sitemap().runSitemap(dr[1].ToString(), counter); 
    counter++; 
}); 

そして、次のようなものを利用できる場合:row_number() OVER (ORDER BY col1) AS iカウンターをスキップできます。これは、戻ってくる行を選択するときに提供されるためですが、私のpostgresの知識では、それが毎回1..100000になるかどうかわかりません上記のコードから、またはそれがあなたが望むものになるかどうか、しかしデータベース管理者の担当者は確かに知っています. これは、コードが次のようになることを意味します。

Parallel.ForEach(recordList, record => 
{ 
    new Sitemap().runSitemap(record.FieldYouNeed, record.RowNumberFromDatabase);
}); 
于 2012-07-12T23:33:52.977 に答える