【问题标题】:Query not using index on timestamp without time zone field在没有时区字段的时间戳上查询不使用索引
【发布时间】:2020-12-15 15:29:52
【问题描述】:

我有一个超过 300 万行的表,其中一个名为 creationdate 的列是 timestamp without time zone

我在上面创建了几个索引,比如:

"idx_routingtasks_creationdate" btree (creationdate)
"idx_routingtasks_creationdate2" btree ((creationdate::date))

当按creationdate::date(按日期转换)过滤时,不使用索引idx_routingtasks_creationdate

explain analyze select * from routingtasks where creationdate::date < (now() - interval '1 day')::date;                                                                                 
                                                             QUERY PLAN                                                             
------------------------------------------------------------------------------------------------------------------------------------
 Seq Scan on routingtasks  (cost=0.00..1315631.93 rows=2811638 width=715) (actual time=186642.012..413763.643 rows=2800659 loops=1)
   Filter: ((creationdate)::date < ((now() - '1 day'::interval))::date)
   Rows Removed by Filter: 212248
 Planning time: 0.195 ms
 Execution time: 413875.829 ms
(5 rows)

不按日期投射时相同:

explain analyze select * from routingtasks where creationdate < now() - interval '1 day';
                                                            QUERY PLAN                                                             
-----------------------------------------------------------------------------------------------------------------------------------
 Seq Scan on routingtasks  (cost=0.00..1300588.39 rows=2918447 width=715) (actual time=72089.312..327288.333 rows=2876756 loops=1)
   Filter: (creationdate < (now() - '1 day'::interval))
   Rows Removed by Filter: 141052
 Planning time: 0.104 ms
 Execution time: 327401.745 ms
(5 rows)

如何在creationdate 列上创建索引以允许此过滤器使用它?

【问题讨论】:

    标签: postgresql


    【解决方案1】:

    答案就在这部分执行计划中:

    Seq Scan ... (actual ... rows=2876756 ...)
      ...
      Rows Removed by Filter: 141052
    

    由于无论如何都会返回几乎所有行,因此使用顺序扫描并丢弃过滤掉的少数行是处理查询的最有效方法。

    如果你想验证,暂时

    SET enable_seqscan = off;
    

    尽可能让 PostgreSQL 避免顺序扫描。然后您可以测试查询执行是否变得更快。

    【讨论】:

      猜你喜欢
      • 2020-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-07
      • 2011-07-15
      • 2010-12-24
      • 1970-01-01
      • 2015-03-01
      相关资源
      最近更新 更多