database - Postgres 仅索引扫描耗时太长
问题描述
我有一个具有以下结构和索引的表:
Table "public.client_data"
Column | Type | Modifiers
-------------------------+---------+-----------
account_id | text | not_null
client_id | text | not null
client_type | text | not null
creation_time | bigint | not null
last_modified_time | bigint | not null
Indexes:
"client_data_pkey" PRIMARY KEY, btree (account_id, client_id)
"client_data_last_modified_time_index" btree (last_modified_time)
从这个表中我需要找到最旧的记录——为此我使用了以下查询:
SELECT last_modified_time FROM client_data ORDER BY last_modified_time ASC LIMIT 1;
但是,在 AWS Aurora Postgres 9.6 的 db.r4.2xlarge RDS 实例中,此表上约有 6100 万行的查询运行速度非常慢(90-100 分钟),没有其他并发查询运行。
但是,将查询更改为使用会DESC
立即完成。可能是什么问题呢?我期待,因为我有一个查询索引,该last_modified_time
查询仅针对按该列排序的该列,并应用了限制,这将涉及一个仅索引查询,该查询应在索引中的第一个条目之后停止。
这是解释分析的输出:
EXPLAIN ANALYZE SELECT last_modified_time FROM client_data ORDER BY last_modified_time ASC LIMIT 1;
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=0.57..2.31 rows=1 width=8) (actual time=6297823.287..6297823.287 rows=1 loops=1)
-> Index Only Scan using client_data_last_modified_time_index on client_data (cost=0.57..1049731749.38 rows=606590292 width=8) (actual time=6297823.287..6297823.287 rows=1 loops=1)
Heap Fetches: 26575013
Planning time: 0.078 ms
Execution time: 6297823.306 ms
DESC
查询结果的版本相同,结果如下
EXPLAIN ANALYZE SELECT last_modified_time FROM client_data ORDER BY last_modified_time DESC LIMIT 1;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=0.57..2.32 rows=1 width=8) (actual time=2.265..2.266 rows=1 loops=1)
-> Index Only Scan Backward using client_data_last_modified_time_index on client_data (cost=0.57..1066049674.69 rows=611336085 width=8) (actual time=2.264..2.264 rows=1 loops=1)
Heap Fetches: 9
Planning time: 0.095 ms
Execution time: 2.278 ms
任何指针?
解决方案
区别在于:
缓慢的计划有
Heap Fetches: 26575013
和快速计划
Heap Fetches: 9
堆提取是将快速仅索引扫描转换为慢速正常索引扫描的原因。
表最近是否经历过大规模更新或删除?
缓慢扫描的原因是它必须在第一次匹配之前遍历许多不可见(已删除)的元组。
在桌子上运行VACUUM
,两次扫描都会很快。
推荐阅读
- amazon-web-services - AWS ec2 userdata ssl验证错误..唯一
- angular - 角度单元测试:属性订阅没有访问类型获取
- apache-beam - 非常小的 BEAM pCollection 没有被刷新到输出文件
- web-services - Sabre PNR 中的历史会计行
- javascript - TypeScript NodeJS req.body 在 POST 请求中为空
- javascript - 如何将无效的变量名变成有效的?
- javascript - 如何将数据从 Javascript 传递到 lua
- javascript - Visual Studio Code 在整个 javascript 文件中显示错误,javascript 没有语法错误(据我所知)
- reactjs - 我可以在反应原生的常规组件周围包裹一个自定义组件吗
- javascript - Gulp 4 默认任务与串行和并行