sql >> Databáze >  >> RDS >> Mysql

Jak zlepšit výkon dotazů (pomocí výsledků příkazu vysvětlení např.)

Můžete zkusit něco takového (i když pro mě není praktické to testovat)

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

Tak doufám, že jsem nic nepokazil.

Myšlenka každopádně spočívá v tom, že ve vnitřním dotazu vyberete pouze řádky, které potřebujete, na základě vaší podmínky kde. To vytvoří menší tabulku tmp, protože vytáhne pouze 2 pole obou int.

Poté se ve vnějším dotazu připojíte k tabulkám, ze kterých ve skutečnosti vytáhnete zbytek dat, seřadíte a seskupíte. Tímto způsobem třídíte a seskupujete na menší datové sadě. A vaše klauzule kde může běžet tím nejoptimálnějším způsobem.

Některé z těchto tabulek můžete dokonce vynechat jako své jediné získávání dat z několika z nich, ale bez zobrazení celého schématu a toho, jak spolu souvisí, je těžké říci.

Ale obecně řečeno tato část (poddotaz)

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

Je to, co je přímo ovlivněno vaší klauzulí WHERE. Podívejte se, abychom mohli optimalizovat tuto část a poté ji použít ke spojení zbývajících dat, která potřebujete.

Příklad odstranění tabulek lze snadno odvodit z výše uvedeného, ​​zvažte toto

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 cluster tabulky se nikdy nepoužívá k vytahování dat, pouze pro kde. Tedy ne

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

Stejné jako

nebo ekvivalentní
WHERE
    sc.cluster_id=?

A proto můžeme toto spojení úplně odstranit.



  1. Chyba:Výplň:Vlastnost SelectCommand.Connection nebyla inicializována.

  2. Chyba Mysql:#1247 - Reference 'karma' není podporována (odkaz na skupinovou funkci)

  3. Pokud je zadáno SELECT DISTINCT, položky ORDER BY se musí objevit ve výběrovém seznamu

  4. Laravel 5.5 pivot join pro získání pivotních hodnot s hlavním výsledkem MySQL