sql >> Base de Datos >  >> RDS >> Mysql

Cómo mejorar el rendimiento de las consultas (usando los resultados del comando de explicación, p. ej.)

Puedes probar algo como esto (aunque no es práctico para mí probar esto)

SELECT
    sac.surveyId,
    q.cat,
    SUM((sac.answer_id*q.weight))/SUM(q.weight) AS score,
    user.division_id,
    user.unit_id,
    user.department_id,
    user.team_id,
    division.division_name,
    unit.unit_name,
    dpt.department_name,
    team.team_name
FROM survey_answers_cache sac
    JOIN
    (
        SELECT
            s.surveyId,
            sc.subcluster_id
        FROM
            surveys s
            JOIN subcluster sc ON s.subcluster_id = sc.subcluster_id
            JOIN cluster c ON sc.cluster_id = c.cluster_id
        WHERE
            c.cluster_id=? AND sc.subcluster_id=? AND s.active=0 AND s.prepare=0
    ) AS v ON v.surveyid = sac.surveyid
    JOIN user ON user.user_id = sac.user_id
    JOIN questions q ON q.question_id = sac.question_id
    JOIN division ON division.division_id = user.division_id
    LEFT JOIN unit ON unit.unit_id = user.unit_id
    LEFT JOIN department dpt ON dpt.department_id = user.department_id
    LEFT JOIN team ON team.team_id = user.team_id
GROUP BY user.team_id, v.surveyId, q.cat
ORDER BY v.surveyId, user.team_id, q.cat ASC

Así que espero no haber estropeado nada.

De todos modos, la idea es que en la consulta interna seleccione solo las filas que necesita en función de su condición de ubicación. Esto creará una tabla tmp más pequeña ya que solo extrae 2 campos, ambos enteros.

Luego, en la consulta externa, se une a las tablas de las que realmente extrae el resto de los datos, ordena y agrupa. De esta manera, está ordenando y agrupando en un conjunto de datos más pequeño. Y su cláusula where puede ejecutarse de la manera más óptima.

Es posible que incluso pueda omitir algunas de estas tablas como su única extracción de datos de algunas de ellas, pero sin ver el esquema completo y cómo está relacionado, es difícil de decir.

Pero hablando en términos generales, esta parte (la subconsulta)

SELECT
    s.surveyId,
    sc.subcluster_id
FROM
    surveys s
    JOIN subcluster sc ON s.subcluster_id = sc.subcluster_id
    JOIN cluster c ON sc.cluster_id = c.cluster_id
WHERE
    c.cluster_id=? AND sc.subcluster_id=? AND s.active=0 AND s.prepare=0

Es lo que se ve directamente afectado por su cláusula WHERE. Mira para que podamos optimizar esta parte y luego usarla para unir el resto de los datos que necesitas.

Un ejemplo de eliminación de tablas se puede deducir fácilmente de lo anterior, considere esto

SELECT
    s.surveyId,
    sc.subcluster_id
FROM
    surveys s
    JOIN subcluster sc ON s.subcluster_id = sc.subcluster_id
WHERE
    sc.cluster_id=? AND sc.subcluster_id=? AND s.active=0 AND s.prepare=0

El c tabla cluster nunca se usa para extraer datos, solo para el dónde. Entonces no es

    JOIN cluster c ON sc.cluster_id = c.cluster_id
 WHERE
    c.cluster_id=?

Igual o equivalente a

WHERE
    sc.cluster_id=?

Y por lo tanto podemos eliminar esa unión por completo.