sql >> Databasteknik >  >> RDS >> Mysql

Hur man förbättrar frågeprestanda (med hjälp av förklara kommandoresultat t.ex.)

Du kan prova något liknande (även om det inte är praktiskt för mig att testa detta)

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

Så jag hoppas att jag inte förstörde något.

Hur som helst, tanken är att i den inre frågan väljer du bara de rader du behöver baserat på ditt where-villkor. Detta kommer att skapa en mindre tmp-tabell eftersom den bara drar 2 fält båda ints.

Sedan i den yttre frågan ansluter du dig till tabellerna som du faktiskt hämtar resten av data från, beställer och grupperar. På så sätt sorterar och grupperar du på en mindre datauppsättning. Och din where-klausul kan köras på det mest optimala sättet.

Du kanske till och med kan utelämna några av dessa tabeller eftersom du bara hämtar data från ett fåtal av dem, men utan att se hela schemat och hur det är relaterat är det svårt att säga.

Men bara generellt sett denna del (underfrågan)

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

Är det som direkt påverkas av din WHERE-klausul. Se så att vi kan optimera den här delen och använd den sedan för att sammanfoga resten av data du behöver.

Ett exempel på att ta bort tabeller kan enkelt härledas från ovanstående, överväg detta

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 tabell cluster används aldrig för att hämta data från, bara för var. Så är inte

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

Samma som eller motsvarande

WHERE
    sc.cluster_id=?

Och därför kan vi eliminera den anslutningen helt.



  1. PHP While loop visar endast sista raden

  2. MySQL-fjärranslutning misslyckas med okänd autentiseringsmetod

  3. Finns det något sätt att tvinga fram MySQL-exekveringsorder?

  4. postgresql - sql - antal "sanna" värden