2012-12-24 148 views
0

這是一個問題。我有一張桌子日期範圍內的記錄 - 表現

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條件。任何人都可以建議更好的解決方案,這也有利於性能

+0

到達將始終> =離開,對嗎? –

+0

是的。抵達時離開時間更大 – Akhil

回答

2

這是一個常見的解決方案,這個問題。每個子查詢都可以通過這種方式使用索引。從@SalmanA

你說得對

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

回覆評論,上述查詢錯過情況是這樣的:

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 
+0

感謝您的支持。但是,如果我們考慮數百萬的數據,工會會因重複檢查而放慢速度。請糾正我,如果我錯了 – Akhil

+0

聯盟只需要從匹配的行中刪除重複項,而不是所有的數百萬行。 –

+0

感謝您的支持。同樣的問題在面試時問我,我也告訴過這個解決方案。但面試官不滿意,並要求更好的解決方案。即使我想不出這個解決方案。這就是爲什麼要檢查更好的可用...再次感謝 – Akhil

1

我想你可以使用此查詢:

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

製作幾SUBST例如, start_date變爲出發,end_date變爲到達等:

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

這不會返回我所有的記錄。例如。如果我的到達日期範圍和間隔時間早於此日期,我仍然希望看到該記錄。希望我已經清楚 – Akhil

+0

試試吧。它應該工作(至少當我用它來檢查衝突的預訂時它是這樣做的)。 –

+0

它返回正確的一組行,但單個索引不能使兩個範圍條件受益。 –

相關問題