从postgres中选择记录,其中时间戳在一定范围内

zzz*_*zzz 48 sql postgresql

我在表保留中有时间戳类型的到达列(我正在使用postgres).例如,我如何选择今年的所有日期?

我知道我可以这样做:

select * FROM reservations WHERE extract(year from arrival) = 2012;
Run Code Online (Sandbox Code Playgroud)

但是我运行了分析,看起来它需要序列扫描.有更好的选择吗?

PS 1嗯.两种方式似乎都需要seq.扫描.但是wildplasser的那个产生的结果更快 - 为什么?

cmm=# EXPLAIN ANALYZE select * FROM reservations WHERE extract(year from arrival) = 2010;
                                                  QUERY PLAN                                                   
---------------------------------------------------------------------------------------------------------------
 Seq Scan on vrreservations  (cost=0.00..165.78 rows=14 width=4960) (actual time=0.213..4.509 rows=49 loops=1)
   Filter: (date_part('year'::text, arrival) = 2010::double precision)
 Total runtime: 5.615 ms
(3 rows)

cmm=# EXPLAIN ANALYZE SELECT * from reservations WHERE arrival > '2010-01-01 00:00:00' AND arrival < '2011-01-01 00:00:00';
                                                                  QUERY PLAN                                                                   
-----------------------------------------------------------------------------------------------------------------------------------------------
 Seq Scan on reservations  (cost=0.00..165.78 rows=51 width=4960) (actual time=0.126..2.491 rows=49 loops=1)
   Filter: ((arrival > '2010-01-01 00:00:00'::timestamp without time zone) AND (arrival < '2011-01-01 00:00:00'::timestamp without time zone))
 Total runtime: 3.144 ms
(3 rows)
Run Code Online (Sandbox Code Playgroud)

**PS 2 - 我在到达列后创建索引第二种方式变得更快 - 因为它看起来像查询使用索引.Mkey - 我想我会用这个蠢话.**

                                                                       QUERY PLAN                                                                        
---------------------------------------------------------------------------------------------------------------------------------------------------------
 Bitmap Heap Scan on reservations  (cost=4.77..101.27 rows=51 width=4960) (actual time=0.359..0.791 rows=49 loops=1)
   Recheck Cond: ((arrival > '2010-01-01 00:00:00'::timestamp without time zone) AND (arrival < '2011-01-01 00:00:00'::timestamp without time zone))
   ->  Bitmap Index Scan on arrival_idx  (cost=0.00..4.76 rows=51 width=0) (actual time=0.177..0.177 rows=49 loops=1)
         Index Cond: ((arrival > '2010-01-01 00:00:00'::timestamp without time zone) AND (arrival < '2011-01-01 00:00:00'::timestamp without time zone))
 Total runtime: 1.265 ms
Run Code Online (Sandbox Code Playgroud)

wil*_*ser 67

SELECT * 
FROM reservations 
WHERE arrival >= '2012-01-01'
AND arrival < '2013-01-01'
   ;
Run Code Online (Sandbox Code Playgroud)

顺便说一句,如果值的分布表明索引扫描不值得(例如,如果所有值都在2012年),优化器仍然可以选择全表扫描.因人而异.解释是你的朋友.


Nay*_*tel 7

在 postgress 中搜索时间戳列直至秒数

select * from "TableName" e
    where timestamp >= '2020-08-08T13:00:00' and timestamp < '2020-08-08T17:00:00';
Run Code Online (Sandbox Code Playgroud)


a_h*_*ame 6

使PostgreSQL使用原始查询的索引的另一个选项是在您正在使用的表达式上创建索引:

create index arrival_year on reservations ( extract(year from arrival) );
Run Code Online (Sandbox Code Playgroud)

这将打开PostgreSQL,可以使用索引

select * 
FROM reservations 
WHERE extract(year from arrival) = 2012;
Run Code Online (Sandbox Code Playgroud)

请注意,索引中的表达式必须与子句中使用的表达式完全相同where才能使其工作.