移行プロジェクト中に、SQL Server で 400 万件のレコードの更新に直面しました。
アップデートはとても簡単です。ブール値フィールドは true/1 に設定する必要があり、入力はこのフィールドに入力する必要があるすべての ID のリストです (1 行に 1 つの ID)。
このサイズの SQL タスクに関しては、私は正確には専門家ではないので、" WHERE xxx IN ( {list of ids, separated by comma} )
" を含む 1 つの UPDATE ステートメントを試してみることから始めました。まず、100 万件のレコードでこれを試しました。テスト サーバー上の小さなデータセットでは、これは魅力的に機能しましたが、運用環境ではエラーが発生しました。そのため、ID のリストの長さを数回短くしましたが、役に立ちませんでした。
次に試したのは、リスト内の各 ID を UPDATE ステートメント (" UPDATE yyy SET booleanfield = 1 WHERE id = '{id}'
") に変換することでした。どこかで、x 行ごとに GO を持つのが良いと読んだので、100 行ごとに GO を挿入しました (unix から移植された優れた「sed」ツールを使用)。
そこで、400 万の更新ステートメントのリストをそれぞれ 250.000 の部分に分割し、それらを SQL ファイルとして保存し、最初のステートメントを SQL Server Management Studio (2008) にロードして実行し始めました。私も SQLCMD.exe を試したことに注意してください。しかし、驚いたことに、これは SQL Studio よりも約 10 倍から 20 倍遅く実行されました。
完了するまでに約 1.5 時間かかり、「クエリがエラーで完了しました」という結果になりました。ただし、messages-list には、「影響を受ける 1 行」と「影響を受ける 0 行」の適切なリストが含まれていました。後者は、id が見つからなかった場合に使用されます。
次に、COUNT(*) を使用してテーブルの更新レコード数を確認したところ、更新ステートメントの数と更新されたレコードの数に数千レコードの違いがあることがわかりました。
その後、レコードが存在しないことが原因ではないかと考えましたが、出力の「0行影響」の量を差し引くと、895レコードの不思議なギャップがありました。
私の質問:
「クエリがエラーで完了しました」のエラーの説明と原因を見つける方法はありますか。
895 レコードという謎のギャップはどのように説明できるのでしょうか?
この更新を行うためのより良い、または最良の方法は何ですか? (私がしていることは非常に非効率的であり、エラーが発生しやすい可能性があると考え始めているため)