sql >> Base de Datos >  >> RDS >> Oracle

Lectura de base de datos de subprocesos múltiples

Red

En primer lugar, desde que usamos rowid y rownum está bloqueado por el proveedor de todos modos, debería considerar el uso de rutinas almacenadas en la base de datos. Podría reducir significativamente la sobrecarga de transmisión de datos desde la base de datos al servidor de aplicaciones (especialmente si están en diferentes máquinas y conectados a través de la red).

Teniendo en cuenta que tiene 80 millones de registros para transmitir, ese podría ser el mejor impulso de rendimiento para usted, aunque depende del tipo de trabajo que realicen sus subprocesos.

Obviamente, aumentar el ancho de banda también ayudaría a resolver los problemas de red.

Rendimiento del disco

Antes de realizar cambios en el código, verifique la carga del disco duro mientras se ejecutan las tareas, tal vez simplemente no pueda manejar tanta E/S (10 subprocesos leyendo simultáneamente).

La migración a SSD/RAID o base de datos en clúster podría resolver el problema. Si bien cambiar la forma en que accede a la base de datos no lo hará en ese caso.

Los subprocesos múltiples podrían resolver los problemas de la CPU, pero las bases de datos dependen principalmente del sistema de disco.

Rownum

Hay un par de problemas que podría enfrentar si lo implementa usando rowid y rownum.

1) número de fila se genera sobre la marcha para los resultados de cada consulta. Entonces, si la consulta no tiene una clasificación explícita y es posible que algún registro tenga un número de fila diferente cada vez que ejecuta la consulta.

Por ejemplo, lo ejecuta por primera vez y obtiene resultados como este:

some_column | rownum
____________|________
     A      |    1
     B      |    2
     C      |    3

luego lo ejecuta por segunda vez, dado que no tiene una clasificación explícita, dbms (por alguna razón que él mismo conoce) decide devolver resultados como este:

some_column | rownum
____________|________
     C      |    1
     A      |    2
     B      |    3

2) el punto 1 también implica que si filtrará los resultados en rownum generará una tabla temporal con TODOS resultados y luego filtrarlo

Así que rownum no es una buena opción para dividir los resultados. Mientras que rowid parecía mejor, también tiene algunos problemas.

Ancho de fila

Si observa la descripción de ROWID puede notar que "el valor de fila identifica de forma única una fila en la base de datos ".

Debido a eso y al hecho de que cuando elimina una fila tiene un "agujero" en la secuencia de ID de fila, es posible que los ID de fila no se distribuyan por igual entre los registros de la tabla.

Entonces, por ejemplo, si tiene tres subprocesos y cada uno obtiene 1 000 000 de ID de fila, es posible que uno obtenga 1 000 000 de registros y los otros dos, 1 registro cada uno. Entonces uno estará abrumado, mientras que otros dos muriendo de hambre .

Es posible que no sea un gran problema en su caso, aunque muy bien podría ser el problema que enfrenta actualmente con el patrón de clave principal.

O si primero busca todos los ID de fila en el despachador y luego los divide por igual (como sugirió peter.petrov), eso podría funcionar, aunque obtener 80 millones de ID todavía parece mucho, creo que sería mejor dividir con uno Consulta SQL que devuelve los bordes de los fragmentos.

O puede resolver ese problema dando una cantidad baja de ID de fila por tarea y usando el marco Fork-Join introducido en Java 7, sin embargo, debería ser usado con cuidado .

Otro punto obvio:tanto rownum como rowid no son portátiles entre bases de datos.

Por lo tanto, es mucho mejor tener su propia columna de "fragmentación", pero luego tendrá que asegurarse de que divide los registros en partes más o menos iguales.

También ten en cuenta que si lo vas a hacer en varios hilos es importante revisar qué modo de bloqueo usa la base de datos , tal vez solo bloquea la tabla para cada acceso, entonces el subprocesamiento múltiple no tiene sentido.

Como sugirieron otros, es mejor que primero encuentre cuál es la razón principal del bajo rendimiento (red, disco, bloqueo de la base de datos, inanición de subprocesos o tal vez simplemente tenga consultas subóptimas:verifique los planes de consulta).