Cer*_*rin 4 postgresql statistics upgrade postgresql-12 query-performance
我在 PostgreSQL 12 数据库中有一个包含数百万条记录的表,从 11 升级到 12 后,一些查询开始表现得很糟糕。他们从大约 1 秒缩短到大约 5 分钟。我尝试重建所有索引、清理以及所有常见的 Postgres 容易实现的目标,但性能仍然很糟糕。
这是查询:
SELECT id, activity_count
FROM user
WHERE (search_index) @@ (to_tsquery('pg_catalog.english', '''1234567890'':*') AND active = true
ORDER BY activity_count DESC LIMIT 101
Run Code Online (Sandbox Code Playgroud)
换句话说,找到与给定帐号匹配的所有活跃用户,并从最活跃到最不活跃进行排序。
此查询大约需要 5 分钟才能返回 2 条记录。有什么不对劲。
该列search_index
是一个 tsvector,存储表的各个文本字段中的所有关键字(只是帐户编号、名称等)。
我为此列创建了一个 GIN 索引:
CREATE INDEX user_search_index_gin
ON public.user USING gin
(search_index)
TABLESPACE pg_default;
Run Code Online (Sandbox Code Playgroud)
我还有一个该active
列的索引:
CREATE INDEX user_active
ON public.user USING btree
(active ASC NULLS LAST)
TABLESPACE pg_default;
Run Code Online (Sandbox Code Playgroud)
我有一个有序索引activity_count
:
CREATE INDEX user_activity_count
ON public.user USING btree
(activity_count ASC NULLS LAST)
TABLESPACE pg_default;
Run Code Online (Sandbox Code Playgroud)
然而,当我跑步时EXPLAIN
,我得到:
"Limit (cost=0.56..11443.66 rows=101 width=1552)"
" -> Index Scan Backward using user_activity_count on user (cost=0.56..36010185.91 rows=317836 width=1552)"
" Filter: (active AND (search_index @@ '''1234567890'':*'::tsquery))"
Run Code Online (Sandbox Code Playgroud)
为什么只使用user_activity_count索引而不使用更高效的GIN索引?我该如何解决?
虽然您的WHERE
条件不是很有选择性,但当前的查询计划对于ORDER BY activity_count DESC LIMIT 101
. 看:
然而,你的谓词让我觉得很有选择性:
WHERE (search_index) @@ (to_tsquery('pg_catalog.english', '''1234567890'':*') AND active = true
Run Code Online (Sandbox Code Playgroud)
除非你的例子'1234567890'
具有误导性。(您确定要在搜索词中使用单引号吗?)这显然不是您使用的实际查询。不匹配的括号。无论如何,您可能需要“简单”的文本搜索配置(加上一些改进):
WHERE search_index @@ to_tsquery('pg_catalog.simple', '''1234567890'':*')
AND active
Run Code Online (Sandbox Code Playgroud)
看:
所以看来你的统计数据不是最新的。
从 11 升级到 12 后,一些查询开始表现得很糟糕。他们从大约 1 秒缩短到大约 5 分钟。我尝试重建所有索引、清理以及所有常见的 Postgres 容易实现的目标,但性能仍然很糟糕。
为什么只使用user_activity_count索引而不使用更高效的GIN索引?
您是否也将所有常用的 Postgres 容易实现的目标ANALYZE
添加到您的篮子中?你肯定没有提到。考虑手册中的说明:
统计数据
由于优化器统计信息不会通过 传输
pg_upgrade
,因此系统将指示您运行命令以在升级结束时重新生成该信息。您可能需要设置连接参数以匹配您的新集群。
如果您的数据库很大vacuumdb
,您可能会对这个选项感兴趣--analyze-in-stages
。(那艘船可能已经驶向手头的案件。)手册:
此选项对于分析从恢复的转储或
pg_upgrade
. 该选项将尝试尽快创建一些统计信息,以使数据库可用,然后在后续阶段生成完整的统计信息。
有关的:
归档时间: |
|
查看次数: |
4256 次 |
最近记录: |