我使用的是 PostgreSQL 14.0。当我执行这个SQL语句时:
explain analyse select xact_commit from pg_stat_database;
我得到一个令人困惑的查询计划,如下所示:
QUERY PLAN:
Subquery Scan on d (cost=0.00..1.11 rows=3 width=8) (actual time-21.502..21.547 rows=8 loops=1)
-> Append (cost=0.00..1.07 rows=3 width=68) (actual time=0.007..0.046 rows=8 loops=1)
-> Subquery Scan on"*SELECT* 1" (cost=0.00..0.02 rows=1 width=68) (actual time=0.006..0.008 rows=1 loops=1)
-> Result (cost=0.00..0.01 rows=1 width=68) (actual time=0.005..0.005 rows=1 loops=1
-> Seq Scan on pg_database (cost=0.00..1.02 rows=2 width=68) (actual time=0.028..0.032 rows=7 loops=1)
Planning Time: 0.556 ms
Execution Time: 21.686 ms
7 rows)
为什么这个SQL查询执行得这么慢(比查询用户表和其他系统表如
pg_class
慢几个数量级)并且不直接使用SeqScan?或者我该如何优化它?
在我的数据库很少的小型测试系统上只需要几分之一毫秒。
就其价值而言,就像您已经提到的那样,
pg_stat_database
是一个系统视图 - 通过使用各种嵌套函数调用来报告许多内容。虽然您只需要 xact_commit
,但您可以将查询剥离到其核心:
SELECT pg_stat_get_db_xact_commit(0) AS xact_commit
UNION ALL
SELECT pg_stat_get_db_xact_commit(oid) AS xact_commit
FROM pg_database;
很大程度上减少了我的计划时间。无论如何应该更快。但测试一下看看。