用于获取PostgreSQL中碎片化索引详细信息的查询

人工智能 2026-07-10

我在找一条查询,用来获取Postgres中索引碎片的统计信息。
我知道pgstattuple,但它会对索引进行实时扫描,代价很高,因此我不想使用它。
我已经用AI找到了下面的查询,但我仍不确定该查询是否可用,或是否能提供准确或接近准确的结果。

SELECT 
            n.nspname AS schemaname,
            c.relname AS indexname
        FROM pg_class c
        JOIN pg_namespace n ON n.oid = c.relnamespace
        JOIN pg_index i ON i.indexrelid = c.oid
        JOIN pg_am am ON c.relam = am.oid
        CROSS JOIN LATERAL (
            SELECT 
                -- This aligns the estimate to actual Postgres Page (Block) boundaries
                (current_setting('block_size')::numeric * CEIL((NULLIF(reltuples, 0) * 90) / current_setting('block_size')::numeric)
                ) AS estimated_visible_size
            FROM pg_class 
            WHERE oid = i.indrelid
        ) est
        WHERE c.relkind = 'i' 
          AND am.amname = 'btree'
          AND i.indisvalid = true 
          AND n.nspname NOT IN ('pg_catalog', 'information_schema')
          AND pg_relation_size(c.oid) > 1024 * 1024 
          -- Apply the 65% threshold using the Lateral-calculated size
          AND (1 - (estimated_visible_size / NULLIF(pg_relation_size(c.oid), 0)::float)) * 100 > 65

解决方案

我不知道那个查询测量的是什么,但它显然与索引碎片无关。

我无法想象有任何查询能为 pgstatindex()leaf_fragmentation 列提供更便宜的替代方案。

如果你想知道一个索引范围扫描在多大程度上会成为顺序读取,你需要 pgstatindex()

是的,调用那个函数确实会扫描整个索引,因此成本不低。
另一方面,也没必要每天收集这些信息。
如果你能找一个每周一次或每月一次运行 pgstatindex() 的时机,那就足以大致了解哪些索引会随着时间退化。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章