This is a common solution to this problem. Each subquery can make use of an index this way.
select flightname from flightdetails where departure between fromDate and toDate
union
select flightname from flightdetails where arrival between fromDate and toDate;
Re comment from @SalmanA
You're right, the query above misses cases like this:
departure < fromDate < toDate < arrival
Since neither departure nor arrival are between the date range, but of course the date range is included in the flight time.
Here's another solution, based on yours but it makes use of indexes both on departure and arrival. Be sure to create compound indexes for each condition:
create index flt_d on flightdetails(flightname, departure);
create index flt_a on flightdetails(flightname, arrival);
select f1.flightname
from flightdetails f1
join flightdetails f2 use index (flt_a)
on f1.flightname = f2.flightname
where f1.departure <= toDate
and f2.arrival >= fromDate;
I tested this out and I had to use the "use index" hint to coax it to use the second index, but when I did I got this optimizer plan:
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: f1
type: index
possible_keys: flt_d,flt_a
key: flt_d
key_len: 20
ref: NULL
rows: 3
Extra: Using where; Using index
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: f2
type: ref
possible_keys: flt_a
key: flt_a
key_len: 12
ref: test.f1.flightname
rows: 1
Extra: Using where; Using index