En una aplicación con tablas federadas, un día de repente nos dió este error:
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException
The last packet sent successfully to the server was XXX seconds ago
Como parecía un problema de timeout, nos metimos al mysql cliente para ver el tiempo que tardaba en ejecutarse la consulta responsable.
En principio no debería tardar casi nada, puesto que era una sentencia WHERE sobre un campo UNIQUE, que solo debía devolver un registro. Y además, la tabla federada sobre la que se realizaba la consulta solo tenía 30 registros en total.
Al ejecutarla devolvía el resultado correcto, pero tardaba alrededor de 8 segundos. Probando desde el mysql ‘servidor’, en el que se encuentran físicamente los datos de la tabla, la consulta se ejecutaba en tiempo normal.
Tras un poco de investigación, descubrimos que el problema era un cúmulo de factores.
- En primer lugar, la tabla sobre la que realizábamos la consulta tenía un campo blob con una imagen de unos pocos cientos de Kbs.
- Eso se unía a que el mysql ‘servidor’ que servía los datos estaba tras una línea ADSL con velocidad de 320Kbps de subida
- Y eso se unía al principal problema, el comportamiento de MySQL con las tablas federadas. En vez de realizar el filtrado de la consulta WHERE en remoto, mysql se baja todos los registros de la tabla federada y hace el filtrado en local. Esto provocaba que en vez de tener que transferir un solo registro con un solo blob de unos cientos de Kbs, estuviese transfiriendo los 30 registros de varios megas en total. No quiero imaginarme cuando tengamos 1000 registros…
Obviamente, en este caso no nos vale de nada aumentar el timeout, la solución pasa por cambiar el diseño de la aplicación.
0 comentarios