Como Marcelo sugiere:
UPDATE mytable
SET new_column = <expr containing old_column>;
Si esto toma demasiado tiempo y falla debido a "instantáneas demasiado viejos" errores (por ejemplo, si la expresión consulta otra mesa altamente activa), y si el nuevo valor para el la columna es siempre NO NULO, puede actualizar la tabla en lotes:
UPDATE mytable
SET new_column = <expr containing old_column>
WHERE new_column IS NULL
AND ROWNUM <= 100000;
Sólo tiene que ejecutar esta declaración, COMMIT, a continuación, ejecute de nuevo; enjuague, repita hasta que informe "0 filas actualizadas". Llevará más tiempo, pero es menos probable que falle cada actualización.
EDIT:
Una mejor alternativa que debe ser más eficiente es el uso de la API de DBMS_PARALLEL_EXECUTE
.
Código Muestra (a partir de documentos de Oracle):
DECLARE
l_sql_stmt VARCHAR2(1000);
l_try NUMBER;
l_status NUMBER;
BEGIN
-- Create the TASK
DBMS_PARALLEL_EXECUTE.CREATE_TASK ('mytask');
-- Chunk the table by ROWID
DBMS_PARALLEL_EXECUTE.CREATE_CHUNKS_BY_ROWID('mytask', 'HR', 'EMPLOYEES', true, 100);
-- Execute the DML in parallel
l_sql_stmt := 'update EMPLOYEES e
SET e.salary = e.salary + 10
WHERE rowid BETWEEN :start_id AND :end_id';
DBMS_PARALLEL_EXECUTE.RUN_TASK('mytask', l_sql_stmt, DBMS_SQL.NATIVE,
parallel_level => 10);
-- If there is an error, RESUME it for at most 2 times.
l_try := 0;
l_status := DBMS_PARALLEL_EXECUTE.TASK_STATUS('mytask');
WHILE(l_try < 2 and l_status != DBMS_PARALLEL_EXECUTE.FINISHED)
LOOP
l_try := l_try + 1;
DBMS_PARALLEL_EXECUTE.RESUME_TASK('mytask');
l_status := DBMS_PARALLEL_EXECUTE.TASK_STATUS('mytask');
END LOOP;
-- Done with processing; drop the task
DBMS_PARALLEL_EXECUTE.DROP_TASK('mytask');
END;
/
Oracle Docs: https://docs.oracle.com/database/121/ARPLS/d_parallel_ex.htm#ARPLS67333
Pocas personas GOTO, el extremo de disabiling 'es INDEX' si está presente en la columna actualizada/instered, y dejar que el trabajo de la noche a la analiza . – Guru
Necesitamos más información. Cuéntanos sobre el esquema de la tabla ... ¿cualquier columna "calculada"? Cualquier índice? 500k - 1m filas NO es una gran cantidad de registros de ninguna manera. – Timothy
Gracias a todos por la respuesta rápida. Me salté la parte que estoy usando declaraciones SQL generadas. Ahora investigué profundamente y parece que las actualizaciones SQL generadas ¡fila por fila! Por lo tanto, cualquier intento de separar en fragmentos de 100 registros no tenía sentido ... Cambiaré el código para generar una instrucción SQL UPDATE adecuada, como en la respuesta aceptada. –