私は簡単だと思っていたことに着手しました: 順番に (行ごとに) 読み取り、いくつかの値を計算し、同じ行を更新してから、テーブル全体の次の行に進みます。
コンテキスト: 1 つのフラット テーブル、2,600 万レコード、複合 PK (4 つの数値)。 物理テーブル サイズ 1.3 GB。レコードが処理される順序は関係ありません。これは、予見可能な将来のために一度だけ行われます。計算が複雑すぎてSQLで実行できません(少なくとも私にとっては:-)
これを行うための推奨される効率的な方法は何ですか?
私が試したこと: in を使用datareader
しADO.NET
ます (古き良き VB6 の結果セットがなくなったため、はるかに簡単になりました)。reader.Read()
ADO.NET は同じ接続でそれを好まないため、各ループ内で更新ステートメント (statement.ExecuteNonQuery) と組み合わせることは注意が必要でした。そのため、2つの接続を開く必要がありました。(更新クエリは WHERE 句で複合 PK を使用します。これは高速である可能性がありますが、更新しようとしているレコードにカーソルが既にあるため、まだ効率が悪いと思います。)
SELECT * FROM MyTable
このアプローチは機能しますが、クエリに基づくリーダーでは機能しません。LIMIT
タイムアウト エラーを回避するために、一度に数千行のチャンクを読み取る必要がありました。初期の実験から、2,600 万件のレコードの処理に 9 時間かかると見積もっています。一晩実行するように設定しましたが、戻ってきたとき、プロセスの 3 分の 1 で再びタイムアウトしていました。再起動した後SELECT
、オフセットが大きくなると、LIMIT 句によってクエリが遅くなることがわかりました。残りの 65% の新しい見積もりは、さらに 20 時間を超えており、LIMIT オフセットが増加するにつれて長くなる可能性があります。
もっといい方法があるはず!?
(私はまた、エレガントであるがもちろんタイムアウトしたEFを試しました:-)