En mi último proyecto, como en otros, trabajo mucho con JSON como formato de transporte de datos entre el cliente y el servidor ya que tanto en Javascript como en los lenguajes de servidor (PHP en mi caso) es muy cómodo utilizarlo.
En este proyecto, estoy guardando una cadena de texto JSON en un campo de una tabla de una base de datos MySQL. Esta cadena de texto JSON contiene varios parámetros de configuración de un usuario que son utilizados por toda la aplicación.
En el lado del servidor, es necesario que esa cadena de texto JSON sea convertida a objeto o array (matriz) para poder acceder a sus datos. En PHP, utilizamos las funciones json_encode y json_decode para las conversiones.
Bien, explicado lo anterior, me plantee la siguiente cuestión: ¿Cual es el modo más eficiente de acceder a estos datos?
Dos son las opciones que me planteé:
- Cuando el usuario se loguea, pedimos a MySQL dicha cadena de texto JSON, la convertimos a array mediante la función json_decode y la almacenamos en $_SESSION, pudiendo acceder a dichos valores hasta que la sesión expire o el usuario cierre la sesión.
Es decir, accedemos una vez a MySQL, convertimos de JSON a array, almacenamos el array en $_SESSION y accedemos muchas veces a $_SESSION. - El usuario se loguea y sólo cuando la aplicación necesite alguno de los datos contenidos en la cadena de texto JSON almacenada en la base de datos, se solicita a MySQL y se convierte a array mediante la función json_decode.
Es decir, accedemos muchas veces a MySQL y cada vez convertimos de JSON a array.
Para muchos, la solución puede parecer obvia, la primera opción debe ser la más eficiente. Es cierto, la primera opción es más eficiente ya que así lo refleja el test que realicé, pero entonces si a primera vista es tan obvia la respuesta ¿porqué me planteé esta cuestión?
La duda que tenía pivotaba sobre varios aspectos:
- El tiempo de proceso que conlleva la deserialización que PHP debe realizar (función unseralize) cada vez que accedemos a un dato almacenado en la variable superglobal $_SESSION.
- El tiempo de localización, acceso y lectura del disco duro del servidor al archivo de sesión correspondiente almacenado en el típico directorio /tmp.
- El tiempo de localización, acceso y lectura del disco duro del servidor al archivo de la base de datos, el de conexión a MySQL y el de ejecución de la petición.
- El tiempo de ejecución de la función json_decode.
Resumiendo: ¿$_SESSION + unserialize o Mysql + json_decode?
Obviamente si la aplicación es utilizada por pocos usuarios, cualquiera de las opciones no supondría un impacto negativo en el rendimiento del servidor.
Sin embargo, los tests realizados demuestran que a medida que el número de usuarios de la aplicación aumenta, la diferencia en rendimiento también aumenta exponencialmente y revela claramente que la combinación $_SESSION + unserialize es mucho más eficiente que MySQL + json_decode.
Espero que a alguien le sea de utilidad lo expuesto en sus proyectos.
Si alguno de vosotros está interesado en el test, que comente y lo publicaré.
¿Os habeis encontrado con este caso u otros parecidos?