INSERT de MySQL: el límite en Laravel

insert

Laravel, el límite INSERT de MySQL

Haciendo algunos DB Seeders surgió un problema porque estaba generando valores y almacenándolos en una matriz, luego insertándolos todos a la vez y luego el INSERT fallaría.

¡Hoy vamos a investigar qué limitaciones tiene!

Considere que tenemos la siguiente tabla:

INSERT


Insertemos 1000 registros a la vez y veamos los resultados, nos detendremos en 100000 registros.

En el primer intento, se detuvo en 45k

INSERTED: 1000 time(s): 0.0094678401947021
INSERTED: 2000 time(s): 0.011389970779419
INSERTED: 3000 time(s): 0.016204833984375
INSERTED: 4000 time(s): 0.022641897201538

INSERTED: 44000 time(s): 0.19947600364685
INSERTED: 45000 time(s): 0.28028988838196

FatalError: Allowed memory size of 134217728 bytes exhausted (tried to allocate 2097160 bytes)

Lo comencé de nuevo y el punto de partida cambió de 1k a 64k

INSERTED: 46000 time(s): 0.22972512245178
INSERTED: 47000 time(s): 0.24145197868347
INSERTED: 48000 time(s): 0.21563100814819

INSERTED: 60000 time(s): 0.29563403129578
INSERTED: 61000 time(s): 0.2987060546875
INSERTED: 62000 time(s): 0.29574394226074

FatalError: Allowed memory size of 134217728 bytes exhausted (tried to allocate 2097160 bytes)

Mismo problema. Es hora de deshabilitar mi límite de memoria de php.ini

¡Probar el número tres!

INSERTED: 1000 time(s): 0.0098659992218018
INSERTED: 2000 time(s): 0.0082449913024902
INSERTED: 3000 time(s): 0.016316890716553
INSERTED: 4000 time(s): 0.020424127578735

INSERTED: 63000 time(s): 0.29119181632996
INSERTED: 64000 time(s): 0.31178092956543
INSERTED: 65000 time(s): 0.32407689094543

Y luego … fallar.

 

QueryException: SQLSTATE[HY000]: General error: 1390 Prepared statement contains too many placeholders…

 

¡Parece que realmente hay un límite! Bien, busquemos entonces. Debería estar entre 65000 y 66000 registros en un INSERT.

Ahora los he repetido insertando 65010, 65020, 65030, y así sucesivamente hasta el primer fallo. Luego llegó al primer número significativo 65530. A partir de ahí he empezado a insertarlos uno por uno…

Y en la final, el límite de INSERT es: 65536 que en realidad es 2 elevado a 16

Idealmente, MySQL permite un número infinito de filas en una declaración INSERT, pero si MySQL Client recibe un paquete más grande que max_allowed_packet (65,636 bytes para MariaDB), arroja un error de paquete demasiado grande y termina la conexión.

Puede omitir esto haciendo esto:

SET GLOBAL max_allowed_packet=524288000; //bytes; SETS TO 500MB

O lo que sea que se adapte a sus necesidades, pero buscaría otras alternativas antes de hacer esto porque establece una configuración GLOBAL.

Recent Post