sql >> Database >  >> RDS >> Mysql

Hoe de prestaties van query's te verbeteren (met behulp van de resultaten van de opdracht explain b.v.)

Je kunt zoiets proberen (hoewel het voor mij niet praktisch is om dit te 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

Dus ik hoop dat ik niets verprutst heb.

Hoe dan ook, het idee is dat je in de innerlijke query alleen de rijen selecteert die je nodig hebt op basis van je waar-voorwaarde. Dit zal een kleinere tmp-tabel creëren omdat het slechts 2 velden trekt, beide ints.

Vervolgens sluit je in de buitenste query aan bij de tabellen waaruit je de rest van de gegevens haalt, rangschikt en groepeert. Op deze manier sorteert en groepeert u op een kleinere dataset. En je waar-clausule kan op de meest optimale manier worden uitgevoerd.

Misschien kun je zelfs sommige van deze tabellen weglaten omdat je alleen gegevens uit een paar van hen haalt, maar zonder het volledige schema te zien en hoe het gerelateerd is, is dat moeilijk te zeggen.

Maar over het algemeen gesproken dit deel (De subquery)

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

Is wat direct wordt beïnvloed door uw WHERE-clausule. Kijk, zodat we dit deel kunnen optimaliseren en het vervolgens kunnen gebruiken om de rest van de gegevens die u nodig hebt samen te voegen.

Een voorbeeld van het verwijderen van tabellen kan eenvoudig worden afgeleid uit het bovenstaande, overweeg dit

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

De c tabel cluster wordt nooit gebruikt om gegevens uit te halen, alleen voor het waar. Dus niet

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

Hetzelfde als of gelijk aan

WHERE
    sc.cluster_id=?

En daarom kunnen we die join volledig elimineren.



  1. Mysql delete-instructie met limiet

  2. Ik heb een probleem wanneer ik left join en group by tegelijkertijd gebruik. Ik heb meerdere rijen met gegevens met dezelfde user_id , dus ik wil group by gebruiken

  3. Controleer of het UTF-8-teken maximaal drie bytes vereist

  4. Hoe SQL-variabelen in PHP te binden?