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.