Hallo Linuchs,
ich habe jetzt eine Testtabelle angelegt und Performance gemessen.
Dein Vorgehen ist aus Sicht der reinen DB Lehre völlig bäh.
Und wie alles vieles, was bäh ist, flutscht es wie ein Zäpfchen. Auf meiner Testtabelle (50000 Rows, 100 Adressen, demnach je Adresse ca 500 Termine) braucht deine Abfrage 30 bis 40 Millisekunden. Egal ob mit oder ohne Index, er macht immer einen Tablescan, den aber fix.
Mein Vorschlag mit der CTE ist deutlich am langsamsten. Ohne Index 2500 Sekunden, mit Primary Index auf (adress_id, tag, uhr) immerhin 250ms.
Die Lösung mit Selfjoin liegt bei 80ms und kommt runter auf 30ms wenn ich eine persistente Zusatzspalte nextTermin in die tabelle lege, die mit CONCAT(tag,'@',uhr) befüllt ist und einen Index auf adress_id und nextTermin lege.
Mit dieser Zusatzspalte und Zusatzindex geht deine Query aber runter auf "Unmessbar kurz" - solange ich das Minimum nur auf tag@uhr bilde. Deine Langfassung mit allen Feldern drin kann wieder den Index nicht nutzen und kommt auf 40ms bis 50ms.
Hier ist der Selfjoin besser als deine Lösung.
Die dedlfixsche Subselect-Lösung ist ebenfalls rasend schnell (0-15ms), kann aber nur eine Spalte liefern. Mischt man wieder Bäh ins Getriebe, d.h. bringt in den Subselect eine CONCAT_WS('@',ort,id,foo,bar,baz) hinein, kann man damit wieder mehr als eine Spalte herausholen und hat unterm Strich die schnellste Lösung.
Aber die Selfjoin-Lösung ist - mit Index und nextTermin-Feld in der DB - konkurrenzfähig und deutlich näher an dem, was SQL ist.
Rolf
sumpsi - posui - obstruxi