나는 다른 방식으로 그것을 시도했고 내가 찾은 최고의 성능은 다음과 같은 간단한 쿼리였습니다.
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
;
... 하나는 다음 ID 가 있는지 확인하기 위해 조인을 남겼습니다. 다음 ID 가없는 경우에만 하위 쿼리가 존재하는 다음 ID를 찾아 간격의 끝을 찾습니다. 같음 (=) 쿼리 가 (>) 연산자 .
sqlfiddle을 사용하면 다른 쿼리의 성능이 크게 다르지 않지만 실제 데이터베이스에서는 위 쿼리가 다른 쿼리보다 3 배 더 빠릅니다.
스키마 :
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)
;
성능을 비교하기 위해 만든 모든 쿼리를 따르십시오.
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
;
누군가를 돕고 유용 할 수도 있습니다.
이 sqlfiddle을 사용하여 내 쿼리를보고 테스트 할 수 있습니다 .
http://sqlfiddle.com/#!9/6bdca7/1