Sabemos que para realizar consultas a la base de datos, disponemos de Eloquent, Query Builder o SQL. Es hora de analizar estas tres herramientas y determinar cual es la mejor a nivel velocidad, consumo y usabilidad.
Ambiente utilizado para las pruebas
- Intel Core i5.
- RAM 8 GB.
- Apache con PHP 7.2.4.
- MySQL 5.7.
- Laravel 5.7.
Para las pruebas cree una tabla posts
con 6 columnas y 55 registros. Y una tabla users
con 6 columnas y 55 registros. Ambas tablas fueron rellenadas con Faker.
Y mido el tiempo con la herramienta Debugbar, pero si tu quieres, puedes hacerlo con otras herramientas (te dejo un artículo con 3 herramientas de Log para Laravel).
Midiendo el tiempo
Esta es la función que voy a utilizar en las tres pruebas para medir el tiempo de ejecución de cada query.
Prueba con Eloquent
Se ejecuto la siguiente prueba para medir una consulta con Eloquent:
Y su resultado fue:
Análisis del resultado de consulta con Eloquent
Analizando el tiempo de la prueba y la información que nos da debugbar. Podemos decir que:
- El tiempo total según el script fue de 0.2296 segundos. Y para debugbar fue de 26.09 ms.
- La request en si tardo 964.37 ms.
- El consumo de memoria RAM de la request fue de 4.51 MB.
- Se ejecutan dos consultas. Muchas veces es mejor hacer dos consultas chicas que una grande. Este no seria el caso, ya que se podría hacerse en una sola consulta simple.
Prueba con Query Builder
Se ejecuta la misma consulta pero utilizando Query Builder:
Y su resultado:
Análisis del resultado de consulta con Query Builder
En esta prueba podes decir que:
- El tiempo total según el script fue de 0.0608 segundos. Y para debugbar fue de 19.43 ms.
- La request en si tardo 766.85 ms.
- El consumo de memoria RAM de la request fue de 4.44 MB.
- Se ejecuta una sola consulta.
Prueba con SQL
Se ejecuta la misma consulta pero utilizando SQL:
Y el resultado con SQL fue:
Análisis del resultado de consulta con SQL
En esta prueba podes decir que:
- El tiempo total según el script fue de 0.0538 segundos. Y para debugbar fue de 19.29 ms.
- La request en si tardo 711.94 ms.
- El consumo de memoria RAM de la request fue de 4.34 MB.
- Se ejecuta una sola consulta.
Aclaración
Las pruebas fueron ejecutadas mas de una vez y la imagen que termine poniendo de cada prueba, son de los tiempos promedios de cada ejecución.
Conclusión
Como pudimos ver, ejecutar las consultas con SQL plano es mas rápido. La request tarda menos en resolverse y consume menos memoria RAM. Esto es lógico ya que no tiene que ejecutar eventos ni resolver métodos de la consulta. Pero su contra parte, es que perdemos la seguridad en la inyección de código SQL.
Por otro lado, vemos que en velocidad se lleva el segundo puesto Query Builder ya que, al igual que con SQL, se realiza una sola consulta y su consumo de memoria y tiempo de request son mas bajo que con Eloquent. Query Builder no hace diferencia de base de datos, por lo tanto, las consultas funcionaran en cualquier motor de base de datos. Pero, su parte negativa es que perdemos la posibilidad de ejecutar eventos.
Y finalmente tenemos a Eloquent. Su consumo de memoria RAM fue mayor, el tiempo de resolución de request también fue mayor y esto es algo lógico ya que Eloquent nos permite ejecutar eventos de cada modelo (entre otras cosas) llevando un mayor procesamiento. Por otro lado, se ejecutaron dos consultas que, como dije antes, no es algo malo dependiendo el caso.
(EDITADO)
En definitiva, todo tiene que ver con lo que estemos desarrollando y el alcance que tenga nuestro proyecto.
- Con SQL ganamos velocidad y tenemos un menor consumo de recursos pero perdemos seguridad y manejo de eventos.
- Con Query Builder ganamos velocidad (no tanta como SQL plano), seguridad y tenemos abstracción de base de datos. Pero perdemos el manejo de eventos.
- Y con Eloquent tenemos disponible abstracción de base de datos, seguridad y manejos de eventos. Pero su consumo y velocidad son peores que las dos anteriores.
Espero que les allá gustado la comparativa. Nos vemos en un próximo articulo.
Hola, qué tal, qué tal sería con más datos? Con una tabla de 5 mil sugeriría las pruebas. Un saludo
Hola amigo, voy a probarlo pero seguramente dará el mismo resultado pero con valores mayores.
Y cómo sería con un Stored Procedure?
es verdad? que tan recomendable seria llamar a un SP en lugar de usar eloquent o query builder? espero que hagas un post aclarando esto! gracias
Ufff estaria Muy buena esa prueba quedo pendiente, he tenido esa curiosidad
Excelente explicación. Te felicito!
Algún consejo para refactorizar los query builder, directamente si mueve como un método más en el modelo?
Pero en caso de llevar parametros la consulta, de que lado se ejecuta el filtrado?
si fueran muchos registros el sp ya entrega solo los filtrados
con eloquent de que lado se ejecuta el where?
Excelente, me sirvió bastante para escoger la mejor solución en mi caso.
Trabajo en una oficina pública y uso query builder para armar padrones, en inconveniente que tengo es que solo permite 16000 registros, mi pregunta es hoy versiones nuevas de query o que procesador me sugueris
Te recomiendo hacerlo paginado para que no traigas tantos registros de un solo tiron.
Notice: Undefined index: excluded_urls in /web/hablemoslaravel/wp-content/plugins/super-progressive-web-apps/public/manifest.php on line 252
mira
Hola que tal a que te refieres manejo de eventos con eloquent? te agradezco.
saludos
Hola, como estás? Me refiero a los eventos que Eloquent dispara si es una query de escritura (updated, created, saved, etc.)
Hola. A lo mejor no estoy teniendo en cuenta algo pero tal como yo lo veo el SQL plano no tiene porque ser inseguro a los ataques SQLinyection… Puedes utilizar Prepared Statements. En mi caso cuando trabajamos sin frameworks de php los utilizamos pero yo el Laravel a penas tengo experiencia y no sé si hay alguna objeción para utilizarlos. Otra manera sería filtrar las variables que entran como se hacía hace muchos años. Un saludo.