Performance pgstattuple查询性能
我正在尝试使用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个对象,它的总执行
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;