2008-09-21 19 views
9

Tengo el código C# que accede a MySQL a través de ODBC.Transacción MySQL con miles de insertos: ¿cuántos "viajes redondos" se necesitan?

Crea una transacción, hace algunos miles insertar comandos y luego confirma. Ahora mi pregunta es ¿cuántos "viajes redondos", por así decirlo, suceden contra el servidor de base de datos? Quiero decir, ¿simplemente transmite cada comando de inserción al servidor de bases de datos, o los almacena en memoria caché/memoria intermedia y los envía en lotes? ¿Y esto es configurable de alguna manera?

Respuesta

18

MySQL tiene un estilo SQL extendida que puede ser utilizado, en donde inserciones de masas se ponen en varios a la vez:

INSERT INTO `table` (`id`, `event`) VALUES (1, 94263), (2, 75015), (3, 75015); 

por lo general voy a recoger a unos pocos cientos de inserción de partes en una cadena antes de ejecutar el SQL consulta en sí. Esto reducirá la sobrecarga del análisis y la comunicación llenándolos usted mismo.

+1

¿Alguna idea de cuántos conjuntos de paréntesis(),(),() se deben considerar como 'grandes'? Lo que quiero preguntar es, ¿cuántas filas de inserción extendidas (= conjuntos de paréntesis después de VALUES) en una consulta deberíamos considerar hacer una nueva consulta? – Swanand

+1

Depende del tamaño de los datos, pero es un lanzamiento entre la elección personal y los límites de tráfico de la base de datos (por ejemplo, el tamaño de 'paquete máximo permitido' de Mysql). Generalmente hago alrededor de 100. Es solo un poco más de tiempo si hay menos por paquete, y no quiero arriesgar ningún problema. –

0

Es difícil decirlo sin ver su código, pero asumo que está ejecutando las declaraciones de a una por vez. Por lo tanto, obtendrá un viaje de ida y vuelta por cada declaración insertada.

En MSSql puede ejecutar múltiples insertos en una sola instrucción:

cmd.ExecuteNonQuery "insert table values (1) insert table values (2)" 

para que pueda crear una cadena grande y ejecutarlo (creo que va a tener un límite), supongo que esto funcionará para MySQL .

También en MSSQL tiene un insertador de lotes (búsqueda "SqlBulkCopy"), en MySQL quizás intente loading the data from a temp file.

+0

No sé acerca de la conexión ODBC de MySQL, pero el propio MySQL permite concatenar varios comandos en una sola ejecución. Además, puedes hacer algo. como "INSERT INTO table VALUES ('hola', 'adios'), ('que', 'alguna vez'); así que responder la pregunta de nickf con la información dada es un poco difícil. :) – hangy

2

Realiza un viaje de ida y vuelta por consulta que envíe (independientemente de si se trata de una transacción o no).

Es posible, en MySQL, utilizar la sintaxis de "inserción extendida" que le permite insertar varias (o incluso muchas) filas en una sola instrucción. Esto generalmente se considera una buena cosa.

0

Cuando usamos MySQL 4.x hace unos años, nos topamos con un límite estricto en el tamaño de la consulta que no era configurable.

Esto probablemente no le ayudará tanto como:

  1. No recuerdo cuál era el límite duro.
  2. Probablemente no estés utilizando MySQL 4.x.
  3. No estábamos usando transacciones.

¡Buena suerte!

2

Un viaje redondo al servidor de base de datos no es lo mismo que un viaje de ida y vuelta a la base de datos en el disco.

Antes de decidir que las vueltas son un cuello de botella, haga algunas mediciones reales.

Hay formas de insertar varias filas con una sola inserción, dependiendo de su DBMS. Antes de invertir el esfuerzo de codificación, averigüe si es probable que le sirva de algo.

0

Depende de dónde invoque la instrucción SQL. Lo intenté una vez con el controlador JDBC de MySQL y recibí un error que decía que el límite es de 1 MB pero es configurable.

No me molesté en tratar de configurarlo y simplemente dividir las sentencias de SQL en partes más pequeñas.

4

No hay límite en el número de filas per se; El límite está en la cantidad de bytes transferidos al servidor.

Puede construir la inserción masiva hasta la cantidad de bytes especificada en 'paquete máximo permitido'. Si quisiera usar la menor cantidad de insertos, lo intentaré.

0

El límite de datos que se enviarán depende de su servidor, por lo que la longitud máxima de varias instrucciones de inserción se ajusta automágicamente para adaptarse. El cuello de botella es una longitud de paquete y una longitud de memoria intermedia.

Ver las net_buffer_length y max_allowed_packet descripciones de variables para obtener más información:

https://dev.mysql.com/doc/refman/5.1/en/server-system-variables.html#sysvar_net_buffer_length https://dev.mysql.com/doc/refman/5.1/en/server-system-variables.html#sysvar_max_allowed_packet

En algunos casos se puede ajustar estos (por ejemplo, al descargar datos) para no generar insertos que son demasiado largos sin embargo, conservar múltiples inserciones. Tenga en cuenta que si tiene algunos blobs en sus tablas o cualquier otro valor largo que pueda exceder los valores de las variables mencionadas, puede obtener errores o datos incompletos.

Cuestiones relacionadas