WITH index_columns AS (
SELECT
n.nspname AS schema_name,
t.relname AS table_name,
t.oid AS table_oid,
i.relname AS index_name,
i.oid AS index_oid,
ix.indisprimary,
ix.indisunique,
ix.indpred IS NOT NULL AS is_partial,
ix.indexprs IS NOT NULL AS is_expression,
pg_get_indexdef(i.oid) AS index_def,
k.pos + 1 AS key_position,
a.attname AS column_name
FROM pg_index ix
JOIN pg_class i
ON i.oid = ix.indexrelid
JOIN pg_class t
ON t.oid = ix.indrelid
JOIN pg_namespace n
ON n.oid = t.relnamespace
CROSS JOIN LATERAL generate_series(0, ix.indnkeyatts - 1) AS k(pos)
LEFT JOIN pg_attribute a
ON a.attrelid = t.oid
AND a.attnum = ix.indkey[k.pos]
WHERE ix.indisvalid
AND n.nspname NOT IN ('pg_catalog', 'information_schema')
)
SELECT
ic.schema_name,
ic.table_name,
ic.index_name,
ic.column_name AS leading_column,
c.reltuples::bigint AS estimated_rows,
s.n_distinct,
CASE
WHEN s.n_distinct > 0 THEN s.n_distinct
WHEN s.n_distinct < 0 THEN abs(s.n_distinct) * c.reltuples
ELSE NULL
END::bigint AS estimated_distinct_values,
round(s.null_frac::numeric, 4) AS null_frac,
s.most_common_vals,
s.most_common_freqs,
ic.is_partial,
ic.is_expression,
ic.index_def
FROM index_columns ic
JOIN pg_class c
ON c.oid = ic.table_oid
LEFT JOIN pg_stats s
ON s.schemaname = ic.schema_name
AND s.tablename = ic.table_name
AND s.attname = ic.column_name
WHERE ic.key_position = 1
ORDER BY
estimated_rows DESC,
estimated_distinct_values NULLS FIRST;