这是个问题。我有桌子

flightdetails
-----------+-------------
flightName | varchar(200)
departure  | date
arrival    | date


我想获取给定日期范围内的所有航班。 fromDate或toDate都应在给定的日期范围内。我知道一个简单的查询,它将给我结果

select flightname from flightdetails where (departure between fromDate and toDate)
or (arrival between fromDate and toDate);


但这对性能不好,因为我使用OR条件。谁能建议一个更好的解决方案,它也有利于性能

最佳答案

这是解决此问题的常用方法。每个子查询都可以通过这种方式使用索引。

select flightname from flightdetails where departure between fromDate and toDate
union
select flightname from flightdetails where arrival between fromDate and toDate;




来自@SalmanA的评论

没错,上面的查询未找到类似这样的情况:

departure < fromDate < toDate < arrival


由于出发和到达时间都不在日期范围之间,因此日期范围当然包括在飞行时间中。

这是基于您的解决方案的另一种解决方案,但是它同时使用了出发和到达时的索引。确保为每个条件创建复合索引:

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;


我对此进行了测试,不得不使用“使用索引”提示来哄骗它使用第二个索引,但是当我这样做时,我得到了这个优化器计划:

*************************** 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

关于mysql - 日期范围内的记录-效果,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14024313/

10-13 09:43