Rolf B: Denkfehler bei SQL-Abfrage?

Beitrag lesen

Hallo Klaus1,

ich habe keinen hinreichend großen Datenbestand, um einen performancerelevanten Test zu machen. Es könnte aber sinnvoll sein, deine Query auf den Kopf zu stellen, so dass nicht für jeden User eine MAX Suche gemacht werden muss.

Kennst Du HAVING?


SELECT vp2.*
FROM (SELECT username, MAX(logindate) as maxlogin
      FROM vpnprotokoll 
      GROUP BY username
      HAVING MAX(logindate) < '2021-04-01') vp1
    JOIN
      vpnprotokoll vp2
    ON vp1.username = vp2.username AND vp1.maxlogin = vp2.logindate
WHERE vp2.status = 'A'
ORDER BY vp2.username

Diese Query ermittelt zunächst für alle User ihr maximales Login-Datum. Mit HAVING wird das auf alle User gefiltert, deren letzter Login vor dem 1.4.21 lag. Wenn Du einen Index auf (username, logindate) oder auch (logindate, username) hast, sollte sich dieser Teil der Query durch einen Index Scan erledigen lassen.

Und erst, wenn das getan ist, werden die eigentlichen Datensätze hinzugemischt. Was pro Satz durch einen Index Seek gemacht werden kann, es sei denn, deine SQL Engine meint, sie könnte das durch einen Tablescan effizienter lösen.

Da hilft dann nur ein EXPLAIN, um das festzustellen, und ggf. Index Hints in der äußeren Query, um einen Index zu erzwingen (mit erneuter Performancemessung; wenn der Query Optimizer meint, ein Tablescan wäre besser, hat er oft recht).

Rolf

--
sumpsi - posui - obstruxi