Vous pouvez essayer quelque chose comme ça (bien que ce ne soit pas pratique pour moi de tester ça)
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
J'espère donc que je n'ai rien gâché.
Quoi qu'il en soit, l'idée est que dans la requête interne, vous ne sélectionnez que les lignes dont vous avez besoin en fonction de votre condition where. Cela créera une table tmp plus petite car elle ne tire que 2 champs à la fois int.
Ensuite, dans la requête externe, vous vous joignez aux tables dont vous extrayez réellement le reste des données, l'ordre et le groupe. De cette façon, vous triez et regroupez sur un ensemble de données plus petit. Et votre clause where peut s'exécuter de la manière la plus optimale.
Vous pourrez peut-être même omettre certaines de ces tables car vous ne tirez que des données de quelques-unes d'entre elles, mais sans voir le schéma complet et son lien, c'est difficile à dire.
Mais d'une manière générale, cette partie (La sous-requête)
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
Est ce qui est directement affecté par votre clause WHERE. Voir afin que nous puissions optimiser cette partie puis l'utiliser pour joindre le reste des données dont vous avez besoin.
Un exemple de suppression de tables peut être facilement déduit de ce qui précède, considérez ceci
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
Le c
table cluster
n'est jamais utilisé pour extraire des données, uniquement pour où. Donc n'est-ce pas
JOIN cluster c ON sc.cluster_id = c.cluster_id
WHERE
c.cluster_id=?
Identique ou équivalent à
WHERE
sc.cluster_id=?
Et donc nous pouvons éliminer complètement cette jointure.