Rolf b: mysql: Erste freie Zahl finden

Beitrag lesen

SELF JOIN deshalb, weil deine Query äquivalent ist zu dieser hier:

SELECT MIN(x.zahl)
FROM numbers x LEFT JOIN numbers y ON x.zahl+1 = y.zahl
WHERE y.zahl is null

Ich habe jetzt mal ein paar SQL Performance-Messungen für deine Nummern gemacht. Um sie nicht durch den Servercache zu verfälschen, habe ich SQL_NO_CACHE hinzugefügt - was Du im Produktionsbetrieb NICHT machen solltest.

SELECT zahl
FROM number x
WHERE NOT EXISTS (SELECT zahl FROM number y WHERE  y.zahl = x.zahl+1)

braucht auf dem von mir genutzten MySQL ca 1,3 Sekunden - weil er ALLE freien Zahlen bestimmt. Meine Tabelle hatte 2560 Einträge mit 10 Lücken. Die Abfrage ist allerdings immer gleich lahm, egal wieviele Lücken ich drin habe.

SELECT MIN(zahl) FROM ...

ist genauso langsam, weil das die gleiche Query ist wie oben, mit einer draufgesetzten MIN() Folgeverarbeitung.

SELECT zahl
FROM number x
WHERE NOT EXISTS (SELECT zahl FROM number y WHERE  y.zahl = x.zahl+1)
LIMIT 1

ist dagegen etwas anderes, weil er jetzt nämlich nach dem ersten Treffer aufhört. Wenn Du einige Lücken hast und die halbwegs verteilt liegen, bist Du deutlich schneller fertig. Dumm nur, dass diese Variante entarten kann. Wenn nämlich keine Lücke existiert, muss er wieder alle durchprobieren und braucht die volle Laufzeit.

Was dagegen richtig hilft, ist ein Primary Index auf die Spalte Zahl. Selbst bei lückenloser Zahlenreihe läuft die Query bei mir dann in 0,006 statt 1,4 Sekunden durch.

Trotzdem ist es ein Index-Scan pro Zahl in der Tabelle. Ob MySQL spezielle Tricks für Satzabgleiche hat, weiß ich nicht. Ich gucke noch.

Rolf