Sql 在被截断的日期字段上使用索引扫描的顺序扫描

Sql 在被截断的日期字段上使用索引扫描的顺序扫描,sql,postgresql,query-performance,Sql,Postgresql,Query Performance,我使用PostgreSQL,我有一个名为table的表。 此表包含一个名为created\u at(data\u typeistimestamptz)的列,该列使用BTREE索引 我想计算一段时间内按在::日期创建的行数(按从日期和结束日期过滤) 我运行以下查询(结果与预期一致): SELECT(“表”。“创建时间”为时区“UTC”)::日期为“日期”, 计数(“表”“id”)为“计数” 从“表” 其中(“表”。“创建时间”>='2018-08-05T00:00:00+00:00'::时间戳和“

我使用PostgreSQL,我有一个名为
table
的表。 此表包含一个名为
created\u at
data\u type
is
timestamptz
)的列,该列使用BTREE索引

我想计算一段时间内按
在::日期
创建的行数(按
从日期
结束日期
过滤)

我运行以下查询(结果与预期一致):

SELECT(“表”。“创建时间”为时区“UTC”)::日期为“日期”,
计数(“表”“id”)为“计数”
从“表”
其中(“表”。“创建时间”>='2018-08-05T00:00:00+00:00'::时间戳和“表”。“创建时间”排序(成本=538741.06..546126.10行=2954016宽度=8)(实际时间=3866.414..4413.922行=2954016循环=1)
排序键:((时区('UTC'::文本,创建时间))::日期)
排序方法:外部合并磁盘:52056kB
->表上的顺序扫描(成本=0.00..140489.32行=2954016宽度=8)(实际时间=0.070..2194.108行=2954016循环=1)

过滤器:((创建时间>='2018-08-05 00:00:00+00'::带时区的时间戳)和(在处创建)您的WHERE条件似乎实际上没有过滤掉任何行,因此表中的所有行都会被处理。在这种情况下,使用Seq扫描是检索数据的最有效方法。如果您将时间范围缩小,以便只检索表中的一小部分行,则优化器应该使用索引

Seq扫描只占用查询时间的一半,另一半时间用于GROUP BY(或其排序)。如果增加
work\u mem
,至少排序/分组应该更快(越多
work\u mem
),排序可能会被哈希聚合所取代


假设
id
被定义为
notnull
,那么使用
count(*)
而不是
count(id)
也会使查询速度更快。其中一个原因是“null检查”计数函数中不再需要。但更重要的是,因为Postgres可能只进行索引扫描,因为只需要在
列创建的列,该列可以直接在索引中使用。如果不切换到只进行索引扫描,您可能需要运行真空分析_表;来更新可见性映射。

thank you@a_horse_,带_no_name,解释清楚。对于第一点,是的,你是对的。对于组员,我将尝试增加和调整
work_mem
。最后一点也很有帮助(影响较小)。
GroupAggregate  (cost=538741.06..605206.42 rows=2954016 width=12) (actual time=3866.460..5077.054 rows=559 loops=1)
  Group Key: ((timezone('UTC'::text, created_at))::date)
  ->  Sort  (cost=538741.06..546126.10 rows=2954016 width=8) (actual time=3866.414..4413.922 rows=2954016 loops=1)
        Sort Key: ((timezone('UTC'::text, created_at))::date)
        Sort Method: external merge  Disk: 52056kB
        ->  Seq Scan on table  (cost=0.00..140489.32 rows=2954016 width=8) (actual time=0.070..2194.108 rows=2954016 loops=1)
              Filter: ((created_at >= '2018-08-05 00:00:00+00'::timestamp with time zone) AND (created_at <= '2020-09-05 00:00:00+00'::timestamp with time zone))
Planning time: 1.018 ms
Execution time: 5094.280 ms