【问题标题】:Postgres: How to setup an index on timestamptz using a time interval?Postgres:如何使用时间间隔在 timestamptz 上设置索引?
【发布时间】:2021-10-05 03:56:35
【问题描述】:

我有一个查询需要使用索引进行优化。有什么方法可以索引 timestamptz 类型的列assigned_at。我正在考虑最初使用assigned_at的GIST索引,有什么方法可以合并它,因为我必须使用now()或传入可变且无法索引的当前日期时间。

select id from foo f where 
f.context_id = $1 
and (f.assigned_at <= (now() - interval '60 second') or f.assigned_at is null) 

打开以获取为此查询设置索引的建议!提前致谢!!

【问题讨论】:

  • 不,我没有!会试试这个,但如果我做了上面的,我怎么能使用索引在时间戳位上创建索引?
  • 这是您要找的吗?这两种情况都使用索引:dbfiddle.uk/…
  • 您的查询包含不平衡的括号。我大概能猜出你的意思,但如果我们不必猜测就好了。

标签: sql postgresql database-indexes


【解决方案1】:

考虑到您发布的查询,使用 context_idassigned_at 的复合索引应该可以解决问题:

CREATE INDEX idx_foo ON foo (context_id,assigned_at);

根据您的数据,OR 条件可能会稍微减慢您的查询速度。另一种方法是将此条件拆分为两个不同的查询:

SELECT * FROM foo f 
WHERE f.context_id = 1 AND f.assigned_at <= (now() - interval '60 second')
UNION ALL
SELECT * FROM foo f WHERE f.context_id = 1 AND f.assigned_at IS NULL;

与往常一样,同时使用查询并测试哪种方法最适合您的数据。

演示:db&lt;&gt;fiddle

【讨论】:

    【解决方案2】:

    (context_id, assigned_at) 上的简单 btree 索引可用于该查询。但要充分使用所有部分,则需要读取索引两次并在它们之间执行 BitmapOr。根据它认为每个术语的选择性,它可能会选择采用不同的方法,例如仅对 context_id 使用索引并将时间部分用作过滤器。

    explain analyze select id from foo f where 
    f.context_id = 7 
    and (f.assigned_at <= (now() - interval '60 second') or f.assigned_at is null);
                                                                     QUERY PLAN                                                                  
    ---------------------------------------------------------------------------------------------------------------------------------------------
     Bitmap Heap Scan on foo f  (cost=8.88..12.90 rows=1 width=4) (actual time=0.031..0.041 rows=7 loops=1)
       Recheck Cond: (((context_id = 7) AND (assigned_at <= (now() - '00:01:00'::interval))) OR ((context_id = 7) AND (assigned_at IS NULL)))
       Filter: ((assigned_at <= (now() - '00:01:00'::interval)) OR (assigned_at IS NULL))
       Heap Blocks: exact=4
       ->  BitmapOr  (cost=8.88..8.88 rows=1 width=0) (actual time=0.024..0.025 rows=0 loops=1)
             ->  Bitmap Index Scan on foo_context_id_assigned_at_idx  (cost=0.00..4.44 rows=1 width=0) (actual time=0.016..0.016 rows=0 loops=1)
                   Index Cond: ((context_id = 7) AND (assigned_at <= (now() - '00:01:00'::interval)))
             ->  Bitmap Index Scan on foo_context_id_assigned_at_idx  (cost=0.00..4.43 rows=1 width=0) (actual time=0.007..0.007 rows=7 loops=1)
                   Index Cond: ((context_id = 7) AND (assigned_at IS NULL))
    

    【讨论】:

      猜你喜欢
      • 2011-11-09
      • 2014-04-04
      • 2018-08-01
      • 2019-05-15
      • 2015-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多