Możesz spróbować czegoś takiego (chociaż nie jest to dla mnie praktyczne, aby to przetestować)
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
Mam więc nadzieję, że niczego nie zepsułem.
W każdym razie pomysł polega na tym, że w wewnętrznym zapytaniu wybierasz tylko potrzebne wiersze na podstawie warunku where. Spowoduje to utworzenie mniejszej tabeli tmp, ponieważ będzie ona pobierać tylko 2 pola w obu int.
Następnie w zewnętrznym zapytaniu dołączasz do tabel, z których faktycznie pobierasz resztę danych, porządkujesz i grupujesz. W ten sposób sortujesz i grupujesz na mniejszym zbiorze danych. A twoja klauzula where może działać w najbardziej optymalny sposób.
Możesz nawet pominąć niektóre z tych tabel jako jedyne pobierające dane z kilku z nich, ale bez wglądu w pełny schemat i jego powiązania trudno powiedzieć.
Ale ogólnie mówiąc ta część (podzapytanie)
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
Czy to, na co bezpośrednio wpływa Twoja klauzula WHERE. Zobacz, abyśmy mogli zoptymalizować tę część, a następnie użyć jej do połączenia pozostałych potrzebnych danych.
Przykład usuwania tabel można łatwo wywnioskować z powyższego, rozważ to
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
c
tabela cluster
nigdy nie jest używany do pobierania danych, tylko do miejsca. Tak nie jest
JOIN cluster c ON sc.cluster_id = c.cluster_id
WHERE
c.cluster_id=?
To samo lub równoważne
WHERE
sc.cluster_id=?
Dlatego możemy całkowicie wyeliminować to połączenie.