Como haces una conversión sobre el campo FECHA, quizás el optimizador no podrá usar el índice correspondiente, en ese caso tendrás que realizar la consulta sin hacer la conversión. Es decir ese filtro es equivalente a :
Código SQL
[-]
where recibo.fecha between :desde and :hasta + 1 and
recibo.fecha <> :hasta + 1 and
recibo.cancelado = :valor
Que es exactamente lo mismo que :
Código SQL
[-]
where recibo.fecha >= :desde and recibo.fecha < :hasta + 1 and
recibo.cancelado = :valor
Aunque este último filtro es más difícil de optimizar para Firebird, puesto que puede necesitar que el índice sobre FECHA sea bidireccional, cosa que no es así en todas las versiones de Firebird.
Todo es cuestión de probar, hasta dar con los índices y la consulta que mejor puede optimizar el motor.
Aunque la consulta por la que te recomiendo empezar es :
Código SQL
[-]
select recibo.nro_recibo,cast(recibo.fecha as date) as fecha, cast(recibo.fecha as time) as hora,
ecografia.nombre as ecografia,
case recibo.porcentaje_cobro when 100 then registro__ecografia.costo
else (recibo.porcentaje_cobro * registro__ecografia.costo) / 100 end as costo,
recibo.costo_total, recibo.literal, recibo.nro_ambulatorio, recibo.usuario, recibo.tipo_paciente, recibo.nro_asegurado,
recibo.nro_internacion, recibo.factura, recibo.monto_cobrar, recibo.porcentaje_cobro, recibo.nro_factura,
registro__ecografia.nro
from recibo
inner join registro__ecografia on registro__ecografia.nro_recibo = recibo.nro_recibo
inner join ecografia on ecografia.nro = registro__ecografiaa.tipo_ecografia
where recibo.fecha between :desde and :hasta + 1 and
recibo.fecha <> :hasta + 1 and
recibo.cancelado = :valor
Saludos.