Actualización de 700 millones de filas al mismo valor

12

Tengo un almacén de datos (oráculo) donde necesito establecer una columna con el mismo valor para los 700 millones de filas.

No tengo acceso de administrador, o acceso a un administrador, por lo que esto debe lograrse con SQL básico y no se crea una tabla temporal.

Para complicar aún más las cosas es si trato de hacer una actualización simple donde 1 = 1, se queda sin espacio para rehacer.

La forma en que lo estoy ejecutando ahora es un bucle como este:

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

pero sé que esto es probablemente ingenuo y debe haber una solución más rápida y elegante.

owook
fuente
¿Está dividida la mesa?
Jack dice que intente topanswers.xyz
No lo creo Hay un par de índices, pero ninguno de ellos involucra la columna que estoy actualizando.
Owook

Respuestas:

4

Si tiene el espacio, puede CTAS usando undo / rehacer mínimo . Si tiene algún índice, hacerlo de cualquier otra manera será muy lento y generará registros como locos.

En el caso de que tenga un único IOT sin ningún índice secundario, o un solo clúster de tabla, puede pasar por la actualización de la clave primaria / clúster en fragmentos sin tener que volver a escanear toda la tabla para encontrar los campos que aún no se han actualizado.

--editar

No puedo crear una tabla secundaria ... Hay un par de índices, pero ninguno de ellos involucra la columna que estoy actualizando.

Luego sugiero dividir la tabla en fragmentos para procesar usando algo que está indexando (incluso si es una sola columna, puede dividirla en rangos de valores) Esto hará un FTS una vez en lugar de una vez para cada fragmento como en su código. Tendrá que vivir con una gran cantidad de rehacer y eliminará su espacio de deshacer también (por lo que no habrá flashback posteriormente)

--editar2

si puede agregar / renombrar / soltar columnas, puede hacerlo de manera muy eficiente , pero solo en 11g

Jack dice que intente topanswers.xyz
fuente
1
Si su DBA le permite hacerlo NOLOGGING, lo que invalidará los hotstandbys.
Cayo
De hecho, y una copia de seguridad después también sería una buena idea, pero este es un almacén y nologginges una herramienta para almacenes
dice Jack intente topanswers.xyz
No puedo crear una tabla secundaria, ciertamente no una tan grande como la primera, aunque solo sea temporal.
Owook
Su enlace de 11g parecía prometedor, pero veo comentarios allí para que para una tabla de 60m todavía era terriblemente lento debido a la necesidad de establecer el valor para cada fila. Como mi tabla es 10 veces ese tamaño, ese método puede no ser una mejora.
owook
@owook no, en 11g esta operación es rápida y no establece el valor para cada fila "para algunos tipos de tablas (por ejemplo, tablas sin columnas LOB)" . Pruébelo en un subconjunto de su mesa ( create table foo as select * from bar where rownum<100000)
Jack dice que intente topanswers.xyz
1

Si usa 11g, suelte la columna y agréguela nuevamente como una columna NO NULA con un valor predeterminado. Esto es contrario a la intuición, pero Oracle almacenará el valor predeterminado en la definición de la tabla, sustituyendo el valor predeterminado en tiempo de ejecución.

Adam Musch
fuente