Estoy implementando la función de importación de datos específicos de la aplicación de una base de datos a otra.
Tengo un archivo CSV que contiene digamos 10000 filas. Estas filas deben insertarse / actualizarse en la base de datos.
Puede haber un caso en el que un par de filas pueden presentarse en la base de datos, lo que significa que deben actualizarse. Si no está presente en la base de datos, es necesario insertarlos.
Una posible solución es que puedo leer una por una línea, verificar la entrada en la base de datos y generar consultas de inserción / actualización en consecuencia. Pero este proceso puede tomar mucho tiempo para crear consultas de actualización / inserción y ejecutarlas en la base de datos. Algunas veces mi archivo CSV puede tener millones de registros.
¿Hay alguna otra forma más rápida de lograr esta función?
OutOfMemory
!Respuestas:
Hay una buena tecnología disponible en Oracle llamada Tablas externas. En su situación, puede acceder a sus datos externos de texto sin formato usando Tablas externas desde la base de datos y actualizar sus datos existentes en la base de datos con declaraciones SQL que le encantan y a las que está acostumbrado, por ejemplo
INSERT
,MERGE
etc.En la mayoría de los casos, usar las utilidades suministradas por Oracle es la mejor manera de realizar ETL. Y debido a que su pregunta se parece más a una administrativa, le sugiero que consulte mi publicación anterior en DBA Stack Exchange "Actualizar la base de datos Oracle desde CSV" .
ACTUALIZACIÓN: Este enfoque funciona bastante bien para leer datos externos en la base de datos. Generalmente, usted define el formato de datos externos cada vez que necesita procesar el archivo de texto sin formato que tiene un nuevo formato. Una vez que se crea la tabla externa, puede consultarla como una tabla de base de datos real. Siempre que haya nuevos datos para importar, simplemente reemplace los archivos subyacentes sobre la marcha sin necesidad de volver a crear tablas externas. Dado que la tabla externa se puede consultar como cualquier otra tabla de base de datos, puede escribir instrucciones SQL para llenar otras tablas de base de datos.
La sobrecarga del uso de tablas externas generalmente es menor en comparación con otras técnicas que implementaría manualmente porque esta tecnología se diseñó teniendo en cuenta el rendimiento teniendo en cuenta la arquitectura de la base de datos Oracle.
fuente
Creo que debería usar SQL * Loader para cargar el archivo CSV en la tabla temporal y luego usar la declaración MERGE para insertar datos en la tabla de trabajo.
SQL * Loader le dará más flexibilidad que las tablas externas y si uno usa la carga de ruta directa, es realmente rápido. Y MERGE hará exactamente lo que necesita: INSERTAR nuevos registros y ACTUALIZAR los existentes.
Par de enlaces para comenzar:
http://docs.oracle.com/cd/B19306_01/server.102/b14215/ldr_concepts.htm
http://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_9016 .htm
fuente
PreparedStatements hará que la creación de consultas de inserción o actualización sea muy rápida. Debe tener tres
PreparedStatements
: uno para insertar, uno para actualizar y otro para verificar si la fila ya está en la tabla. Si puede mantener las ID iguales entre el archivo CSV y la nueva base de datos, entonces verificar si hay una fila usando el campo primaryID también debería ser muy rápido.El uso de una inserción por lotes puede ofrecer una ganancia de rendimiento. A medida que transmite a través del archivo CSV, verificará si la fila ya está allí y luego realizará una actualización o agregará la fila a su comando de inserción por lotes. Debe verificar esta pregunta SO para la comparación de velocidad de estos dos enfoques.
Si la importación de esta base de datos es algo que debe hacerse regularmente y el rendimiento es un problema utilizando el método que describí anteriormente, puede intentar manejar la tarea con múltiples subprocesos de trabajo. Utilice tantos subprocesos como procesadores en la máquina que ejecuta este código.
Cada subproceso tiene su propia conexión de base de datos y, a medida que su código itera a través del archivo, se pueden pasar líneas de CSV a los distintos subprocesos. Esto es mucho más complicado, por lo que solo haría esto si los requisitos de rendimiento me obligan.
fuente