开发者社区> 问答> 正文

[查询优化] PG 分区表日期范围查询索引问题 now() vs 日期字符串

PG 版本 12.5 采用 INHERITS 创建基于时间(按月)的分区表,并给每个分表的时间列均建立了索引,目前已有 12 个月的分表。 需求及问题:通过视图获取今日数据,但条件中使用 now() 会扫描所有的分表索引,而日期字符串仅会扫描对应日期范围的表及索引,如何进行修改来实现这一需求?谢谢

查询语句

SELECT *
   FROM table w
  WHERE ((w."time" > ((now())::date + '00:00:00'::time without time zone)) AND (w."time" < ((now())::date + '23:59:59'::time without time zone)))

执行计划

Append  (cost=0.00..114.54 rows=1123 width=24)
  ->  Seq Scan on table w  (cost=0.00..0.00 rows=1 width=24)
        Filter: (("time" > ((now())::date + '00:00:00'::time without time zone)) AND ("time" < ((now())::date + '23:59:59'::time without time zone)))
  ->  Index Scan using table_202102_index_time on table_202102 w_1  (cost=0.29..2.51 rows=1 width=24)
        Index Cond: (("time" > ((now())::date + '00:00:00'::time without time zone)) AND ("time" < ((now())::date + '23:59:59'::time without time zone)))
  ->  Index Scan using table_202103_index_time on table_202103 w_2  (cost=0.30..2.52 rows=1 width=24)
        Index Cond: (("time" > ((now())::date + '00:00:00'::time without time zone)) AND ("time" < ((now())::date + '23:59:59'::time without time zone)))
  ->  Index Scan using table_202009_index_time on table_202009 w_3  (cost=0.16..2.38 rows=1 width=24)
        Index Cond: (("time" > ((now())::date + '00:00:00'::time without time zone)) AND ("time" < ((now())::date + '23:59:59'::time without time zone)))
  ->  Index Scan using table_202010_index_time on table_202010 w_4  (cost=0.29..2.51 rows=1 width=24)
        Index Cond: (("time" > ((now())::date + '00:00:00'::time without time zone)) AND ("time" < ((now())::date + '23:59:59'::time without time zone)))
  ->  Index Scan using table_202011_index_time on table_202011 w_5  (cost=0.17..2.39 rows=1 width=24)
        Index Cond: (("time" > ((now())::date + '00:00:00'::time without time zone)) AND ("time" < ((now())::date + '23:59:59'::time without time zone)))
  ->  Index Scan using table_202012_index_time on table_202012 w_6  (cost=0.29..2.51 rows=1 width=24)
        Index Cond: (("time" > ((now())::date + '00:00:00'::time without time zone)) AND ("time" < ((now())::date + '23:59:59'::time without time zone)))
  ->  Index Scan using table_202101_index_time on table_202101 w_7  (cost=0.30..2.52 rows=1 width=24)
        Index Cond: (("time" > ((now())::date + '00:00:00'::time without time zone)) AND ("time" < ((now())::date + '23:59:59'::time without time zone)))
  ->  Index Scan using table_202104_index_time on table_202104 w_8  (cost=0.30..2.52 rows=1 width=24)
        Index Cond: (("time" > ((now())::date + '00:00:00'::time without time zone)) AND ("time" < ((now())::date + '23:59:59'::time without time zone)))
  ->  Index Scan using table_202105_index_time on table_202105 w_9  (cost=0.30..2.52 rows=1 width=24)
        Index Cond: (("time" > ((now())::date + '00:00:00'::time without time zone)) AND ("time" < ((now())::date + '23:59:59'::time without time zone)))
  ->  Index Scan using table_202106_index_time on table_202106 w_10  (cost=0.30..2.52 rows=1 width=24)
        Index Cond: (("time" > ((now())::date + '00:00:00'::time without time zone)) AND ("time" < ((now())::date + '23:59:59'::time without time zone)))
  ->  Index Scan using table_202107_index_time on table_202107 w_11  (cost=0.30..2.52 rows=1 width=24)
        Index Cond: (("time" > ((now())::date + '00:00:00'::time without time zone)) AND ("time" < ((now())::date + '23:59:59'::time without time zone)))
  ->  Index Scan using table_202108_index_time on table_202108 w_12  (cost=0.30..2.52 rows=1 width=24)
        Index Cond: (("time" > ((now())::date + '00:00:00'::time without time zone)) AND ("time" < ((now())::date + '23:59:59'::time without time zone)))
  ->  Index Scan using table_202109_index_time on table_202109 w_13  (cost=0.30..2.52 rows=1 width=24)
        Index Cond: (("time" > ((now())::date + '00:00:00'::time without time zone)) AND ("time" < ((now())::date + '23:59:59'::time without time zone)))
  ->  Index Scan using table_202110_index_time on table_202110 w_14  (cost=0.30..2.52 rows=1 width=24)
        Index Cond: (("time" > ((now())::date + '00:00:00'::time without time zone)) AND ("time" < ((now())::date + '23:59:59'::time without time zone)))
  ->  Index Scan using table_202111_index_time on table_202111 w_15  (cost=0.30..73.91 rows=1108 width=24)
        Index Cond: (("time" > ((now())::date + '00:00:00'::time without time zone)) AND ("time" < ((now())::date + '23:59:59'::time without time zone)))

查询语句

explain SELECT *
   FROM table w
  WHERE w.time>= '2021-11-17';

执行计划

Append  (cost=0.00..74.46 rows=1154 width=24)
  ->  Seq Scan on table w  (cost=0.00..0.00 rows=1 width=24)
        Filter: ("time" >= '2021-11-17 00:00:00'::timestamp without time zone)
  ->  Index Scan using table_202111_index_time on table_202111 w_1  (cost=0.29..68.69 rows=1153 width=24)
        Index Cond: ("time" >= '2021-11-17 00:00:00'::timestamp without time zone)

查询语句修改为以下,还是会扫描所有的表索引

explain ANALYZE  SELECT *
   FROM table w
  WHERE w.time >= CURRENT_DATE;

求助,如何优化索引以及查询语句?谢谢!

展开
收起
1584944066300731 2021-11-17 12:59:55 902 0
0 条回答
写回答
取消 提交回答
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
PostgresChina2018_赖思超_PostgreSQL10_hash索引的WAL日志修改版final 立即下载
低代码开发师(初级)实战教程 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载