简体   繁体   English

日期范围内的记录-效果

[英]Records within date range - Performance

Here is a problem. 这是个问题。 I have a table 我有桌子

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

I want to get all the flights in the given date range. 我想获取给定日期范围内的所有航班。 Either fromDate or toDate should be inside the given daterange. fromDate或toDate都应在给定的日期范围内。 I know of a simple query which will give me the result 我知道一个简单的查询,它将给我结果

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

But this not good for performance as I use an OR condition. 但这对性能不好,因为我使用OR条件。 Can anyone suggest a better solution which favours performance too 谁能建议一个更好的解决方案,它也有利于性能

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 来自@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

I think you could use this query: 我认为您可以使用以下查询:

 -- 2.2) select date ranges that overlap [d1, d2] (d2 and end_date are inclusive) SELECT * FROM <table> WHERE @d2 >= start_date AND end_date >= @d1 

Making few substitutions eg start_date becomes departure, end_date becomes arrival, etc: 进行很少的替换,例如start_date成为出发,end_date成为到达,等等:

SELECT flightname
FROM   flightdetails
WHERE  toDate >= departure AND arrival >= fromDate

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM