0

我们正在将我们的 postgres 数据库从版本 9.3.14 升级到 9.4.9。我们目前处于测试阶段。我们在测试时遇到了一个问题,当数据库更新到 9.4.9 时会导致 CPU 使用率过高。有些查询 Postgres 9.4 正在使用 primary_key_index 而有更便宜的选项。例如,为以下查询运行解释分析:

SELECT  a.id as a_id, b.col_id as col_id
FROM a
INNER JOIN b ON b.id = a.b_id
WHERE (a.col_text = 'pqrs' AND a.col_int = 1)
ORDER BY a.id ASC LIMIT 1

给出了这个:

Limit  (cost=0.87..4181.94 rows=1 width=8) (actual time=93014.991..93014.992 rows=1 loops=1)
 ->  Nested Loop  (cost=0.87..1551177.78 rows=371 width=8) (actual time=93014.990..93014.990 rows=1 loops=1)
       ->  Index Scan using a_pkey on a  (cost=0.43..1548042.20 rows=371 width=8) (actual time=93014.968..93014.968 rows=1 loops=1)
             Filter: ((col_int = 1) AND ((col_text)::text = 'pqrs'::text))
             Rows Removed by Filter: 16114217
       ->  Index Scan using b_pkey on b  (cost=0.43..8.44 rows=1 width=8) (actual time=0.014..0.014 rows=1 loops=1)
             Index Cond: (id = a.b_id)
Planning time: 0.291 ms
Execution time: 93015.041 ms

虽然 9.3.14 中相同查询的查询计划给出了这样的:

Limit  (cost=17.06..17.06 rows=1 width=8) (actual time=5.066..5.067 rows=1 loops=1)
 ->  Sort  (cost=17.06..17.06 rows=1 width=8) (actual time=5.065..5.065 rows=1 loops=1)
       Sort Key: a.id
       Sort Method: quicksort  Memory: 25kB
       ->  Nested Loop  (cost=1.00..17.05 rows=1 width=8) (actual time=5.047..5.049 rows=1 loops=1)
             ->  Index Scan using index_a_on_col_text on a  (cost=0.56..8.58 rows=1 width=8) (actual time=3.154..3.155 rows=1 loops=1)
                   Index Cond: ((col_text)::text = 'pqrs'::text)
                   Filter: (col_int = 1)
             ->  Index Scan using b_pkey on b  (cost=0.43..8.46 rows=1 width=8) (actual time=1.888..1.889 rows=1 loops=1)
                   Index Cond: (id = a.b_id)
Total runtime: 5.112 ms

如果我从查询中删除 ORDER BY 子句,则查询可以使用适当的索引正常工作。我可以理解,在这种情况下(使用 ORDER BY),规划器正在尝试使用主键索引来扫描所有行并获取有效行。但显然使用 sort 显然要便宜得多。

我已经探索过像enable_indexscanenable_seqscan这样的 Postgres 参数,它们默认是. 我们希望将其留在数据库中以决定进行索引扫描或顺序扫描。我们还尝试调整Effective_cache_sizerandom_page_costseq_page_costenable_sort也打开了。

它不仅发生在这个特定的查询中,而且还有一些其他查询正在使用 primary_key_index 而不是其他可能的有效方法。

PS:

4

1 回答 1

0

在向 AWS Support 提交案例后,我得到了以下信息:

我了解到您想知道您最近升级的实例性能下降的原因。这是 Postgres 实例上升级的预期和一般行为。升级完成后,您需要在每个用户数据库上运行 ANALYZE 以更新表的统计信息。这也使 SQL 性能更好。更好的方法是使用 Vacuumdb[1],如下所示:

Vacuumdb -U [您的​​用户] -d [您的数据库] -Ze -h [您的 rds 端点]

它只会优化您的数据库执行计划,不会释放空间,但会比完全清空花费更少的时间。

这已经解决了这个问题。希望这可以帮助其他偶然发现此类问题的人。

于 2018-01-21T16:04:34.310 回答