SoFunction
Updated on 2025-04-08

Postgresql to view tables and indexes, and determine whether it is expanded

Several sources of index inflation:

1 After a large number of deletions occur, the index pages are sparse, reducing the index usage efficiency.

2 In versions before PostgresQL, vacuum full will also cause sparse index pages.

3 Long-running transactions prohibit the cleanup of tables by vacuum, which causes the sparse page status to remain.

View duplicate indexes

SELECT pg_size_pretty(SUM(pg_relation_size(idx))::BIGINT) AS SIZE,
  (array_agg(idx))[1] AS idx1, (array_agg(idx))[2] AS idx2,
  (array_agg(idx))[3] AS idx3, (array_agg(idx))[4] AS idx4
FROM (
 SELECT indexrelid::regclass AS idx, (indrelid::text ||E'\n'|| indclass::text ||E'\n'|| indkey::text ||E'\n'||
           COALESCE(indexprs::text,'')||E'\n' || COALESCE(indpred::text,'')) AS KEY
 FROM pg_index) sub
GROUP BY KEY HAVING COUNT(*)>1
ORDER BY SUM(pg_relation_size(idx)) DESC;

The size of the table and the number of indexes in the table

SELECT
 ,
 indexname,
  AS num_rows,
 pg_size_pretty(pg_relation_size(quote_ident()::text)) AS table_size,
 pg_size_pretty(pg_relation_size(quote_ident(indexrelname)::text)) AS index_size,
 CASE WHEN indisunique THEN 'Y'
  ELSE 'N'
 END AS UNIQUE,
 idx_scan AS number_of_scans,
 idx_tup_read AS tuples_read,
 idx_tup_fetch AS tuples_fetched
FROM pg_tables t
LEFT OUTER JOIN pg_class c ON =
LEFT OUTER JOIN
 ( SELECT  AS ctablename,  AS indexname,  AS number_of_columns, idx_scan, idx_tup_read, idx_tup_fetch, indexrelname, indisunique FROM pg_index x
   JOIN pg_class c ON  = 
   JOIN pg_class ipg ON  = 
   JOIN pg_stat_all_indexes psai ON  =  )
 AS foo
 ON  = 
WHERE ='public'
ORDER BY 1,2;

Get the number of rows, indexes and some information about these indexes (more detailed)

SELECT
 pg_class.relname,
 pg_size_pretty(pg_class.reltuples::BIGINT) AS rows_in_bytes,
 pg_class.reltuples AS num_rows,
 COUNT(indexname) AS number_of_indexes,
 CASE WHEN x.is_unique = 1 THEN 'Y'
  ELSE 'N'
 END AS UNIQUE,
 SUM(CASE WHEN number_of_columns = 1 THEN 1
    ELSE 0
   END) AS single_column,
 SUM(CASE WHEN number_of_columns IS NULL THEN 0
    WHEN number_of_columns = 1 THEN 0
    ELSE 1
   END) AS multi_column
FROM pg_namespace 
LEFT OUTER JOIN pg_class ON pg_namespace.oid = pg_class.relnamespace
LEFT OUTER JOIN
  (SELECT indrelid,
   MAX(CAST(indisunique AS INTEGER)) AS is_unique
  FROM pg_index
  GROUP BY indrelid) x
  ON pg_class.oid = 
LEFT OUTER JOIN
 ( SELECT  AS ctablename,  AS indexname,  AS number_of_columns FROM pg_index x
   JOIN pg_class c ON  = 
   JOIN pg_class ipg ON  =  )
 AS foo
 ON pg_class.relname = 
WHERE 
  pg_namespace.nspname='public'
AND pg_class.relkind = 'r'
GROUP BY pg_class.relname, pg_class.reltuples, x.is_unique
ORDER BY 2;

Supplement: postgresql view table inflation

View table inflation (sort the inflation rate of all table products)

The SQL article is as follows:

SELECT
 schemaname||'.'||relname as table_name,
 pg_size_pretty(pg_relation_size(schemaname||'.'||relname)) as table_size,
 n_dead_tup,
 n_live_tup,
 round(n_dead_tup * 100 / (n_live_tup + n_dead_tup),2) AS dead_tup_ratio
FROM
 pg_stat_all_tables
WHERE
 n_dead_tup >= 1000
ORDER BY dead_tup_ratio DESC
LIMIT 10;

The above is personal experience. I hope you can give you a reference and I hope you can support me more. If there are any mistakes or no complete considerations, I would like to give you advice.