59

テーブル予約にtimestampタイプの到着列があります(postgresを使用しています)。たとえば、今年内のすべての日付を選択するにはどうすればよいですか?

私はこのようなことをすることができることを知っています:

select * FROM reservations WHERE extract(year from arrival) = 2012;

しかし、analyzeを実行しましたが、シーケンススキャンが必要なようです。より良いオプションはありますか?

PS1うーん。どちらの方法でも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)

** PS 2-到着時にインデックスを作成した後、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
4

3 に答える 3

82
SELECT * 
FROM reservations 
WHERE arrival >= '2012-01-01'
AND arrival < '2013-01-01'
   ;

ところで、値の分布がインデックススキャンに価値がないことを示している場合(たとえば、すべての値が2012年にある場合)、オプティマイザーは全表スキャンを選択できます。YMMV。説明はあなたの友達です。

于 2012-09-15T16:14:47.800 に答える
7

PostgreSQLに元のクエリのインデックスを使用させる別のオプションは、使用している式にインデックスを作成することです。

create index arrival_year on reservations ( extract(year from arrival) );

これによりPostgreSQLが開き、次のインデックスを使用できるようになります。

select * 
FROM reservations 
WHERE extract(year from arrival) = 2012;

インデックス内の式は、これを機能させるために句で使用されているものとまったく同じ式である必要があることに注意してください。where

于 2012-09-15T19:40:36.503 に答える
3

postgressのタイムスタンプ列を秒単位で検索します

select * from "TableName" e
    where timestamp >= '2020-08-08T13:00:00' and timestamp < '2020-08-08T17:00:00';
于 2020-08-13T13:13:28.520 に答える