Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Langsame Abfrage mit HAVING-Klausel – kann ich sie beschleunigen?

Eine schnelle Lösung wäre das Filtern in der Unterabfrage:

SELECT count(d.id) AS dcount, s.id, s.name
FROM sites s
LEFT JOIN deals d ON (s.id = d.site_id AND d.is_active = 1)
WHERE (s.is_active = 1)
AND s.id IN(
    SELECT g.site_id
    FROM gstats g
    WHERE g.start_date > '2015-04-30' AND g.site_id = s.id
    GROUP BY g.site_id
    HAVING SUM(g.results) > 100
)
GROUP BY s.id
ORDER BY dcount ASC

Denn sonst machen Sie eine solche Gruppierungsabfrage für jeden möglichen Kandidaten. Mit EXISTS können wir das eleganter gestalten :

SELECT count(d.id) AS dcount, s.id, s.name
FROM sites s
LEFT JOIN deals d ON (s.id = d.site_id AND d.is_active = 1)
WHERE (s.is_active = 1)
AND EXISTS (
    SELECT 1
    FROM gstats g
    WHERE g.site_id = s.id AND g.start_date > '2015-04-30'
    HAVING SUM(g.results) > 100
)
GROUP BY s.id
ORDER BY dcount ASC

Aber wir sind noch nicht fertig, jetzt verwenden wir den EXISTS für alle Element. Das ist seltsam, da die Abfrage nur von s.id abhängt , es hängt also nur von der Gruppe ab , nicht die einzelnen Zeilen. Also ein Potenzial Beschleunigung, aber das hängt von der Größe der Tabellen usw. ab, ist die Bedingung auf ein HAVING zu verschieben Aussage:

SELECT count(d.id) AS dcount, s.id, s.name
FROM sites s
LEFT JOIN deals d ON (s.id = d.site_id AND d.is_active = 1)
WHERE (s.is_active = 1)
GROUP BY s.id
ORDER BY dcount ASC
HAVING EXISTS (
    SELECT 1
    FROM gstats g
    WHERE g.site_id = s.id AND g.start_date > '2015-04-30'
    HAVING SUM(g.results) > 100
)