7億行を同じ値に更新する


12

データウェアハウス(オラクル)があり、7億行すべてに対して同じ値に列を設定する必要があります。

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

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

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

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

しかし、私はこれがおそらく素朴であり、より迅速でよりエレガントなソリューションが必要であることを知っています。


テーブルはパーティション化されていますか?
ジャックはtopanswers.xyz

私はそうは思わない。インデックスはいくつかありますが、更新中の列には関係しません。
owook

回答:


4

スペースがあれば、最小限のundo / redoを使用してCTASを実行できます。インデックスがある場合、他の方法でインデックスを作成すると非常に遅くなり、異常なログが生成されます。

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

-編集

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

次に、インデックス付けするものを使用して処理するためにテーブルをチャンクに分割することをお勧めします(単一のカラムであっても、値の範囲に分割することができます)これは、コード。あなたは非常に多くのやり直しで生活しなければならず、あなたのアンドゥスペースも一掃します(したがってフラッシュバックはありません)

--edit2

列を追加/名前変更/ドロップできる場合、これを非常に効率的行うことができます、11gのみ


1
DBAがNOLOGGING許可すると、ホットスタンバイが無効になります。
ガイウス

確かに、その後のバックアップも良いアイデアですが、これは倉庫であり、倉庫nologging用のツールです
ジャックはtopanswers.xyzを試す11

一時的なテーブルであっても、確かに最初のテーブルほど大きくないセカンダリテーブルを作成することはできません。
owook

11gのリンクは有望に見えましたが、60mのテーブルではすべての行に値を設定する必要があるため、依然として非常に遅いというコメントがあります。私のテーブルはそのサイズの10倍なので、その方法は改善されないかもしれません。
owook

いいえ@owook、この操作を11gの上に迅速であり、すべての行の値を設定しない「のテーブルのいくつかのタイプ(LOB列せず、例えば、テーブル)のために」。テーブルのサブセットで試してみてください(create table foo as select * from bar where rownum<100000
ジャックはtopanswers.xyzを試す11

1

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.