2010-08-08 40 views
5

¿Cuál es la forma mejor/más eficiente de insertar 1000 filas en una tabla (base de datos jdbc/connector-mysql)? (es un búfer y necesita ser volcado en la base de datos cada vez que está lleno)Inserción múltiple múltiple de SQL

1- ¿Una declaración de SQL autocatenada/concanated?

2- for (int i = 0; i<1000; i++) { con.prepareStatement(s.get(i)); } con.commit();

3- procedimiento almacenado?

¿introducción de datos a granel a través de un archivo?

5- (su solución)

Respuesta

2

The LOAD DATA INFILE statement es probablemente su mejor apuesta para el rendimiento. (# 4 de su lista de opciones anterior) Aunque probablemente necesite más código para realizar su tarea, ya que necesita crear el archivo intermedio, llévelo al servidor y luego llame a LOAD DATA para ingresarlo en su db.

páginas MySql Ayuda citan:

El comando LOAD DATA INFILE lee filas de un archivo de texto en una tabla en una velocidad muy alta.

+0

Utilice este enfoque con precaución. He visto sistemas que han hecho esto en el pasado y el costo de crear el archivo intermedio y enviarlo al servidor ha superado los beneficios de rendimiento del uso de la operación de carga rápida de archivos. –

+0

Parece muy peligroso ya que tenemos dos servidores de aplicaciones que acceden simultáneamente a la misma base de datos. Realmente temía que surgiera esa respuesta. Gracias a todos por su respuesta. –

0

Puede utilizar insertos lotes JDBC.

PreparedStatement ps = cn.prepareStatement("INSERT INTO...."); 

for (int i = 0; i < 1000; i++) { 
    ps.setString(1, "value-" + i); // Set values 
    ps.addBatch();     // Add this to the batch 
    ps.clearParameters();   // Reset the parameters 
} 

ps.executeBatch(); 

Sin embargo MySQL no soporta la funcionalidad de lote de forma nativa, así que para obtener un rendimiento razonable, necesitará añadir rewriteBatchedStatements=true a la configuración JDBC de MySQL.

También hay una sintaxis de inserción por lotes específica de MySQL que puede usar si desea crear una cadena de SQL grande. Intentaría ambos y probaría el rendimiento.

INSERT INTO x (a,b) 
    VALUES ('1', 'one'), 
      ('2', 'two'), 
      ('3', 'three'); 

Tenga cuidado con ambos enfoques, ya que puede exceder el tamaño máximo de paquete para una sola solicitud. Es posible que deba establecer un tamaño de lote que sea diferente al número de entradas en su búfer. P.ej. es posible que necesite dividir 1000 entradas en 10 lotes de 100.

0

Tenga en cuenta que JDBC se confirma automáticamente después de cada declaración, a menos que explícitamente indique que no. Si lo hace y ejecuta X inserciones antes de ejecutar la confirmación, debería mejorar bastante su rendimiento.

+0

me olvidé de escribir que estaba usando c3p0. entonces tengo que comprometerme al final. –