Este SQL te devuelve una lista de números entre 1 y 100.
Código SQL
[-]with recursive n as (
select 1 as n
from rdb$database
union all
select n.n + 1
from n
where n < 100
)
select n.n
from n;
Con esto como base restrinjo el rango al min/max id de la tabla articulos.
De este rango devuelvo solo los que no existen en la tabla de artículos.
Se parece a la respuesta de Neftali, pero para Firebird.
El único problema es que debido a la recursividad solo permite rangos de 1024 registros.
Código SQL
[-]WITH RECURSIVE N
AS (SELECT (SELECT MIN(ID)
FROM ARTICULOS) AS N
FROM RDB$DATABASE
UNION ALL
SELECT N.N + 1
FROM N
WHERE
N < (SELECT MAX(ID)
FROM ARTICULOS))
SELECT N.N
FROM N
WHERE
NOT EXISTS(SELECT ID
FROM ARTICULOS
WHERE
ID = N.N)
Con respecto a la velocidad, lo he probado con una tabla con 800 registros indexados por el ID y no ha tardado nada.