Hay situaciones que requieren tener una consulta realmente grande uniendo varias tablas junto con sentencias de subselección para producir los resultados deseados.
Mi pregunta es, ¿deberíamos considerar el uso de múltiples consultas más pequeñas y llevar las operaciones lógicas a la capa de aplicación consultando la base de datos en más de una llamada o es mejor tenerlas todas a la vez?
Por ejemplo, considere la siguiente consulta:
SELECT *
FROM `users`
WHERE `user_id` IN (SELECT f2.`friend_user_id`
FROM `friends` AS f1
INNER JOIN `friends` AS f2
ON f1.`friend_user_id` = f2.`user_id`
WHERE f2.`is_page` = 0
AND f1.`user_id` = "%1$d"
AND f2.`friend_user_id` != "%1$d"
AND f2.`friend_user_id` NOT IN (SELECT `friend_user_id`
FROM `friends`
WHERE `user_id` = "%1$d"))
AND `user_id` NOT IN (SELECT `user_id`
FROM `friend_requests`
WHERE `friend_user_id` = "%1$d")
AND `user_image` IS NOT NULL
ORDER BY RAND()
LIMIT %2$d
¿Cuál es la mejor manera de hacerlo?
fuente
Como alguien que tiene que apoyar / limpiar estas consultas grandes y complicadas, diría que es mucho mejor separarlas en varios pequeños trozos fáciles de entender. No es necesariamente mejor desde el punto de vista del rendimiento, pero al menos le está dando a SQL una mejor oportunidad para llegar a un buen plan de consulta.
Haz la vida más fácil a las personas que te siguen y ellos dirán cosas buenas sobre ti. Haz que sea difícil para ellos y te maldecirán.
fuente
Mis 2 centavos en las 2 palabras clave consulta-rendimiento y escalabilidad:
Rendimiento de la consulta: el paralelismo de SQL Server ya hace un muy buen trabajo desglosando las consultas en búsquedas de subprocesos múltiples, por lo que no estoy seguro de cuánto mejorará el rendimiento de la consulta al hacerlo para SQL Server. Sin embargo, tendrá que mirar el plan de ejecución para ver cuánto grado de paralelismo obtiene cuando lo ejecuta y comparar los resultados en ambos sentidos. Si termina teniendo que usar una sugerencia de consulta para obtener el mismo o mejor rendimiento, entonces IMO no vale la pena ya que la sugerencia de consulta podría no ser óptima más adelante.
Escalabilidad: leer las consultas puede ser más fácil, como dijo Datagod, y dividirlas en consultas separadas tiene sentido si puede usar sus nuevas consultas en otras áreas también, pero si no las va a usar también para otras llamadas, entonces habrá incluso más procesos almacenados para administrar para 1 tarea, y la OMI no contribuiría a la escalabilidad.
fuente
LIMIT
Algunas veces, no hay más remedio que dividir la consulta grande / compleja en consultas pequeñas. La mejor manera de determinar eso sería usar una
EXPLAIN
declaración con laSELECT
declaración. El número de trazas / escaneos que su db va a hacer para obtener sus datos es el producto de los valores de "filas" devueltos por suEXPLAIN
consulta. En nuestro caso, tuvimos una consulta que unía 10 tablas. Para un registro particular, la traza ascendió a 409M que blogueó nuestra base de datos y aumentó el uso de la CPU de nuestro servidor de base de datos en más del 300%. Pudimos recuperar la misma información dividiendo las consultas mucho más rápido.En resumen, en algunos casos, dividir una consulta compleja / grande tiene sentido, pero en otros puede generar muchos problemas de rendimiento o mantenimiento y esto debería tratarse caso por caso.
fuente