Lectura de la base de datos a través de múltiples hilos en java

Estoy leyendo datos de la base de datos vertica usando múltiples hilos en java. Tengo alrededor de 20 millones de registros y estoy abriendo 5 hilos diferentes con consultas seleccionadas como esta ...

start = threadnum;

while (start*20000<=totalRecords){

    select * from tableName order by colname limit 20000 offset start*20000.

    start +=5;

}

La consulta anterior asigna 20K registros distintos para leer desde db a cada hilo. por ejemplo, el primer hilo leerá primero 20k registros luego 20K registros comenzando desde la posición 100 000, etc.

Pero no estoy mejorando el rendimiento. De hecho, usar un solo hilo si tarda x segundos en leer 20 millones de registros, entonces se tarda casi x segundos en leer cada hilo de la base de datos. ¿No debería haber alguna mejora de x segundos (esperaba x / 5 segundos)?

¿Alguien puede determinar qué está yendo mal?

Respuesta 1

no hay nada que salga mal más que su comprensión de qué situaciones pueden mejorarse mediante subprocesos múltiples y qué situaciones pueden no mejorar.

Su base de datos presumiblemente se encuentra en un disco; ese es un disco con un conjunto de cabezas que se mueven todas al unísono, por lo que es lo mismo que decir que es un disco con una sola cabeza. La cabeza toma tiempo para moverse de un lugar a otro; Eso se llama tiempo de búsqueda .

Cuando lee datos secuenciales de un hilo, la cabeza tiene que moverse muy poco de una pista a otra.

Cuando está leyendo diferentes flujos de datos secuenciales de varios subprocesos, la cabeza tiene que moverse mucho para saltar de una pista a otra que está muy lejos, y luego volver a la primera. Eso es mucha búsqueda por encima.

Y luego, por supuesto, su disco duro está conectado a su placa base utilizando un solo cable, por lo que todos esos datos (después de toda la sobrecarga de búsqueda) deben pasar a través de él antes de que puedan ser procesados ​​por sus diferentes hilos.

El resultado es, por supuesto, muy mal rendimiento.

La lección para llevar a casa es esta:

La E / S masiva del mismo dispositivo nunca se puede mejorar con subprocesos múltiples.

Para decirlo en términos diferentes: el paralelismo en el procesamiento de datos nunca aumenta el rendimiento cuando todos los datos provienen de una sola fuente secuencial.

Si tuviera 5 bases de datos diferentes almacenadas en 5 discos diferentes, eso funcionaría mejor. (Y si también tuviera esos discos conectados a 5 controladores IDE separados en su placa base, eso funcionaría aún mejor).

Respuesta: 2

No repetiré lo que dice Mike Nakis, ya que es cierto y está bien explicado:

La E / S de un disco físico no se puede mejorar con subprocesos múltiples

Sin embargo, me gustaría agregar algo.

Cuando ejecutas una consulta como esa:

 select * from tableName order by colname limit 20000 offset start*20000.

desde el lado del cliente, puede manejar el resultado de la consulta que podría mejorar utilizando múltiples hilos.

Pero desde el lado de la base de datos, usted no tiene la mano en el procesamiento de la consulta y la base de datos Vertica probablemente esté diseñada para ejecutar su consulta realizando tareas paralelas de acuerdo con las posibilidades de la máquina.

Entonces, desde el lado del cliente, puede dividir la ejecución de su consulta en uno, dos o tres subprocesos paralelos, finalmente no debería cambiar muchas cosas, ya que una base de datos profesional está diseñada para optimizar el tiempo de respuesta de acuerdo con la cantidad de solicitudes que recibe y la máquina posibilidades

Respuesta: 3

Tengo problemas para descubrir cómo encontrar la aparición de los números dentro de una matriz 2D. Soy nuevo en Java, así que tengo que hacer este programa sin usar mapas / soluciones avanzadas. Ejemplo: dado ...

Un ejemplo rápido es una colección del nombre y apellido de los usuarios. Un método requiere que compare usando el primer nombre, otro usando el apellido. ¿Es posible tener dos compareTo () diferentes? ...

Cómo crear esto: JButton b = new JButton ("text"). AddActionListener (e -> classX.addNewTest ())); botones.add (b); en una linea? Intenté esto: panel.add (b = new JButton ("text"). AddActionListener (e ...

Mi aplicación ya está publicada en Play Store cuando actualice esta aplicación, luego Genere un paquete firmado / APK y luego elegiré la ruta existente pero "No se encontró ninguna clave con el alias 'clave 0' en el almacén de claves" este mensaje ...