![](/img/trans.png)
[英]Ruby on Rails - Select records within date range (slow performance)
[英]Records within date range - Performance
這是個問題。 我有桌子
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
我認為您可以使用以下查詢:
-- 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
進行很少的替換,例如start_date成為出發,end_date成為到達,等等:
SELECT flightname
FROM flightdetails
WHERE toDate >= departure AND arrival >= fromDate
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.