2017-09-25 64 views
0

我選擇基於日期範圍的行使用下面的SQL工作,但是這是一個有效的方法。正如你所看到的日期和時間是在不同的領域舉行。從我的記憶中或者在你將一個函數放在一個屬性周圍的時候開始進行Oracle工作,它不能使用索引。Postgres結合日期和時間字段,這是有效的

select * 
from events 
where venue_id = '2' 
and  EXTRACT(EPOCH FROM (start_date + start_time)) 
between EXTRACT(EPOCH FROM ('2017-09-01 00:00')::timestamp) 
and  EXTRACT(EPOCH FROM ('2017-09-30 00:00')::timestamp) 

那麼有沒有辦法做到這一點,可以使用索引?

+3

爲什麼要提取新紀元?爲什麼不只是'start_date + start_time BETWEEN'2017-09-01 00:00':: timestamp AND'2017-09-30 00:00':: timestamp'? – Andreas

回答

1

前言:由於查詢被限制在一個單一的venue_id,下面兩個實例中創建具有第一venue_id的化合物的索引。

如果你想爲改善查詢的索引,你可以創建一個expression index

CREATE INDEX events_start_idx 
ON events (venue_id, (EXTRACT(EPOCH FROM (start_date + start_time)))); 

如果你不想專門的功能指標,您可以創建在start_date普通索引列,並添加額外的邏輯來使用索引。然後該索引將訪問計劃限制在日期範圍內,並且在第一個和最後一個日期中錯誤時間的附帶記錄被過濾掉。

在下面,我也消除了不必要的時代提取。

CREATE INDEX events_venue_start 
ON events (venue_id, start_date); 
SELECT * 
FROM events 
WHERE venue_id = '2' 
AND  start_date BETWEEN '2017-09-01'::date AND '2017-09-30'::date 
AND  start_date + start_time BETWEEN '2017-09-01 00:00'::timestamp 
            AND '2017-09-30 00:00'::timestamp 

WHERE條款的前兩個部分將使用索引來充分受益。最後一部分是使用過濾器找到的索引記錄。

+0

'start_date BETWEEN'2017-09-01':: date AND'2017-09-30':: date'實際需要嗎? –

+0

@BenEdwards是的,否則它不能完全使用索引。 – Andreas