2017-09-25 63 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