Ich habe es auf verschiedene Arten versucht und die beste Leistung, die ich gefunden habe, war diese einfache Abfrage:
select a.id+1 gapIni
,(select x.id-1 from arrc_vouchers x where x.id>a.id+1 limit 1) gapEnd
from arrc_vouchers a
left join arrc_vouchers b on b.id=a.id+1
where b.id is null
order by 1
;
... eine linke Verknüpfung, um zu überprüfen, ob die nächste ID vorhanden ist, nur wenn die nächste nicht gefunden wird, findet die Unterabfrage die nächste vorhandene ID, um das Ende der Lücke zu finden. Ich habe es getan, weil eine Abfrage mit gleichem (=) eine bessere Leistung hat als ein Operator mit mehr als (>).
Bei Verwendung der SQL-Geige wird die Leistung anderer Abfragen nicht so unterschiedlich angezeigt , aber in einer realen Datenbank führt diese obige Abfrage dreimal schneller als andere.
Das Schema:
CREATE TABLE arrc_vouchers (id int primary key)
;
INSERT INTO `arrc_vouchers` (`id`) VALUES (1),(4),(5),(7),(8),(9),(10),(11),(15),(16),(17),(18),(19),(20),(21),(22),(23),(24),(25),(26),(27),(28),(29)
;
Befolgen Sie die folgenden Abfragen, um die Leistung zu vergleichen:
select a.id+1 gapIni
,(select x.id-1 from arrc_vouchers x where x.id>a.id+1 limit 1) gapEnd
from arrc_vouchers a
left join arrc_vouchers b on b.id=a.id+1
where b.id is null
order by 1
;
select *, (gapEnd-gapIni) qt
from (
select id+1 gapIni
,(select x.id from arrc_vouchers x where x.id>a.id limit 1) gapEnd
from arrc_vouchers a
order by id
) a where gapEnd <> gapIni
;
select id+1 gapIni
,(select x.id from arrc_vouchers x where x.id>a.id limit 1) gapEnd
#,coalesce((select id from arrc_vouchers x where x.id=a.id+1),(select x.id from arrc_vouchers x where x.id>a.id limit 1)) gapEnd
from arrc_vouchers a
where id+1 <> (select x.id from arrc_vouchers x where x.id>a.id limit 1)
order by id
;
select id+1 gapIni
,coalesce((select id from arrc_vouchers x where x.id=a.id+1),(select x.id from arrc_vouchers x where x.id>a.id limit 1)) gapEnd
from arrc_vouchers a
order by id
;
select id+1 gapIni
,coalesce((select id from arrc_vouchers x where x.id=a.id+1),concat('*** GAT *** ',(select x.id from arrc_vouchers x where x.id>a.id limit 1))) gapEnd
from arrc_vouchers a
order by id
;
Vielleicht hilft es jemandem und nützlich.
Sie können meine Abfrage mit dieser SQL-Geige sehen und testen :
http://sqlfiddle.com/#!9/6bdca7/1