Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Jak poprawić wydajność zapytań (używając wyników polecenia wyjaśnij np.)

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.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Mysql 5.7.20:Nie można utworzyć wartości JSON z ciągu znaków za pomocą ZESTAWU ZNAKÓW „binary”

  2. Zapytanie trwa bardzo długo przy pierwszym uruchomieniu

  3. Pozycja użytkownika MYSQL SELECT (więcej niż x i mniej niż y)

  4. Tablica PHP mysql pobiera każdy rekord

  5. Jak wybrać encje przez wywołanie procedury składowanej za pomocą Spring Data?