web-dev-qa-db-ja.com

7億行を同じ値に更新

7億行すべての列を同じ値に設定する必要があるデータウェアハウス(Oracle)があります。

私は管理者アクセス、または管理者へのアクセス権を持っていないので、これは基本的なSQLで実行する必要があり、一時テーブルは作成されません。

さらに複雑なのは、1 = 1の単純な更新を実行しようとすると、REDOスペースが不足することです。

私が今それを実行している方法は、次のようなループです:

loop
  update mytable set mycolumn = '1' where mycolumn is null and rownum < 50000;
  commit;
end loop

しかし、私はこれがおそらく素朴であり、より速くよりエレガントな解決策がなければならないことを知っています。

12
owook

スペースがある場合は、 最低限の元に戻す/やり直しを使用するCTAS を実行できます。インデックスがある場合、それを他の方法で行うと非常に遅くなり、狂ったようにログが生成されます。

セカンダリインデックスのない単一のIOT、または単一のテーブルクラスターがある場合は、テーブル全体を再スキャンして、まだ更新されていないフィールドを見つける必要なく、チャンクでプライマリ/クラスターキーの更新をステップ実行できます。

-編集

セカンダリテーブルを作成できません...インデックスは2つありますが、更新する列に関連するものはありません。

次に、インデックスを作成するものを使用して処理するためにテーブルをチャンクに分割することをお勧めします(単一の列であっても、値の範囲に分割できます)これにより、チャンクごとに1回ではなく1回FTSが実行されますコード。非常に多くのやり直しを行う必要があり、元に戻すスペースも一掃されます(その後のフラッシュバックはありません)。

--edit2

列を追加/名前変更/削除できる場合、 これを非常に効率的に実行できます 、ただし11gのみ

11gを使用している場合は、列をドロップして、デフォルト値を持つNOT NULL列として追加します。これは直観に反しますが、Oracleはデフォルト値を実行時にデフォルト値に置き換えて、テーブルの定義に格納します。

1
Adam Musch