Memperbarui 700 juta baris ke nilai yang sama

12

Saya punya data warehouse (oracle) di mana saya perlu mengatur kolom ke nilai yang sama untuk semua 700 juta baris.

Saya tidak memiliki akses admin, atau akses ke admin, jadi ini harus diselesaikan dengan sql dasar dan tidak ada tabel temp yang dibuat.

Masalah rumit selanjutnya adalah jika saya mencoba melakukan pembaruan sederhana di mana 1 = 1, itu kehabisan ruang redo.

Cara saya menjalankannya sekarang adalah perulangan seperti ini:

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

tapi saya tahu ini mungkin naif dan harus ada solusi yang lebih cepat dan lebih elegan.

Owook
sumber
Apakah tabel dipartisi?
Jack bilang coba topanswers.xyz
Saya tidak percaya begitu. Ada beberapa indeks, tetapi tidak ada yang melibatkan kolom yang saya perbarui.
Owook

Jawaban:

4

Jika Anda memiliki ruang, Anda dapat CTAS menggunakan undo / redo minimal . Jika Anda memiliki indeks sama sekali, melakukannya dengan cara lain akan sangat lambat dan menghasilkan logging seperti orang gila.

Dalam kasus di mana Anda memiliki IOT tunggal tanpa indeks sekunder, atau satu cluster tabel, Anda bisa melangkah melalui pembaruan kunci primer / cluster dalam potongan tanpa harus menelusuri ulang seluruh tabel untuk menemukan bidang yang belum diperbarui.

--edit

Saya tidak dapat membuat tabel sekunder ... Ada beberapa indeks, tetapi tidak satupun yang melibatkan kolom yang saya perbarui.

Kemudian saya sarankan untuk memecah tabel menjadi potongan-potongan untuk diproses menggunakan sesuatu yang Anda indeks (bahkan jika itu adalah satu kolom, Anda dapat membaginya menjadi rentang nilai) Ini akan melakukan FTS satu kali, bukan satu kali untuk setiap potongan seperti pada Anda kode. Anda harus hidup dengan banyak redo dan akan menghapus ruang undo Anda juga (jadi tidak ada flashback selanjutnya)

--edit2

jika Anda dapat menambah / mengganti nama / menjatuhkan kolom, Anda dapat melakukannya dengan sangat efisien , tetapi hanya pada 11g

Jack mengatakan coba topanswers.xyz
sumber
1
Jika DBA Anda memungkinkan Anda melakukannya NOLOGGING, itu akan membuat hotstandbys tidak valid.
Gayus
Memang, dan cadangan setelah itu akan menjadi ide yang bagus juga - tetapi ini adalah gudang dan nologgingalat untuk gudang
Jack mengatakan coba topanswers.xyz
Saya tidak dapat membuat tabel sekunder, tentu saja tidak sebesar yang pertama, meskipun hanya sementara.
Owook
Tautan 11g Anda terlihat menjanjikan, tetapi saya melihat komentar di sana bahwa untuk tabel 60m itu masih sangat lambat karena harus menetapkan nilai untuk setiap baris. Karena meja saya 10x ukuran itu, metode itu mungkin bukan perbaikan.
Owook
@ lihat tidak, pada 11g operasi ini cepat dan tidak menetapkan nilai untuk setiap baris "untuk beberapa jenis tabel (misalnya, tabel tanpa kolom LOB)" . Cobalah di subset dari meja Anda ( create table foo as select * from bar where rownum<100000)
Jack mengatakan coba topanswers.xyz
1

Jika Anda menggunakan 11g, jatuhkan kolom dan tambahkan kembali sebagai kolom BUKAN NULL dengan nilai default. Ini kontra-intuitif, tetapi Oracle akan menyimpan nilai default dalam definisi tabel, menggantikan nilai default pada saat run time.

Adam Musch
sumber