Mysql
 sql >> Datenbank >  >> RDS >> Mysql

So verbessern Sie die Abfrageleistung (z. B. mithilfe von EXPLAIN-Befehlsergebnissen)

Sie können so etwas versuchen (obwohl es für mich nicht praktikabel ist, dies zu testen)

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

Ich hoffe also, ich habe nichts vermasselt.

Wie auch immer, die Idee ist, dass Sie in der inneren Abfrage nur die Zeilen auswählen, die Sie basierend auf Ihrer Where-Bedingung benötigen. Dadurch wird eine kleinere tmp-Tabelle erstellt, da nur 2 Felder gezogen werden, beides ints.

Dann verknüpfen Sie in der äußeren Abfrage die Tabellen, aus denen Sie die restlichen Daten tatsächlich abrufen, ordnen und gruppieren. Auf diese Weise sortieren und gruppieren Sie auf einem kleineren Datensatz. Und Ihre Where-Klausel kann optimal ausgeführt werden.

Möglicherweise können Sie sogar einige dieser Tabellen weglassen, da Sie nur Daten aus einigen von ihnen ziehen, aber ohne das vollständige Schema und seine Beziehungen zu sehen, ist das schwer zu sagen.

Aber ganz allgemein gesagt dieser Teil (Die Unterabfrage)

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

Ist das, was direkt von Ihrer WHERE-Klausel betroffen ist. Sehen Sie nach, damit wir diesen Teil optimieren können, und verwenden Sie ihn dann, um den Rest der benötigten Daten zusammenzuführen.

Ein Beispiel für das Entfernen von Tabellen lässt sich leicht aus dem Obigen ableiten, bedenken Sie dies

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

Das c Tabelle cluster wird nie verwendet, um Daten abzurufen, nur für das Wo. Also nicht

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

Das Gleiche wie oder Äquivalent zu

WHERE
    sc.cluster_id=?

Und deshalb können wir diesen Join komplett eliminieren.