Performance pgstattuple查询性能

Performance pgstattuple查询性能,performance,postgresql,statistics,query-performance,Performance,Postgresql,Statistics,Query Performance,我正在尝试使用pgstattuple扩展构建一个查询,用于检查所有用户表中的死元组、活元组百分比、可用空间等。所以,我提出了这个问题: SELECT schemaname, relname, (pgstattuple(schemaname ||'.'||relname)).* FROM pg_statio_user_tables; pg_statio_user_tables是一个pg_目录视图,它使用另一个系统视图。因此,乍一看,查询看起来非常简单,但对于数据库中的882个对象,它的总执行

我正在尝试使用pgstattuple扩展构建一个查询,用于检查所有用户表中的死元组、活元组百分比、可用空间等。所以,我提出了这个问题:

SELECT schemaname, 
relname, 
(pgstattuple(schemaname ||'.'||relname)).*
FROM pg_statio_user_tables;
pg_statio_user_tables是一个pg_目录视图,它使用另一个系统视图。因此,乍一看,查询看起来非常简单,但对于数据库中的882个对象,它的总执行时间为27分钟

此查询的执行计划:


有没有办法重写仍然使用pgstattuple的查询,使其执行得更好?

如果在子查询中运行该函数,并且只在下一级分解生成的行类型,则速度会快得多:

SELECT s.schemaname, s.relname, st.*
FROM pg_statio_user_tables s
    ,pgstattuple(s.schemaname ||'.'|| s.relname) AS st;
(这是一个隐式的
横向联接
。在Postgres 9.3之前的版本中,使用子查询代替。)

这样,在
pg\u statio\u user\u表中,每行只调用一次函数。不幸的是,您在Postgres查询规划器(解析器)中遇到了一个弱点。克雷格在这一相关回答中详细解释:

如果从
pg_statio_user_tables
视图中只需要表和模式名,那么您可以更快地获得:


您的查询速度快了多少?我的查询需要561486.985毫秒(~9,4分钟),您的查询需要横向连接:155152.465毫秒(2,6分钟),pg_类169894.413毫秒(2,8分钟)。冈萨雷斯的速度还远远不够,但要好得多:)
SELECT c.oid::regclass::text AS tbl, (st).*
FROM   pg_class c
JOIN   pg_namespace n ON n.oid = c.relnamespace
      ,pgstattuple(c.oid::regclass::text) st
WHERE  c.relkind = 'r'            -- only tables
AND    n.nspname NOT LIKE 'pg_%'  -- exclude system schemas
ORDER  BY 1;