Skip to content

Index analysis queries #14

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions index_analysis_content_indexes.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
-- Indexes in 'public' schema that are
-- "content" indexes, i.e. they aren't system indexes
-- for primary keys, unique constraints
SELECT
n.nspname AS schema_name,
c.relname AS index_name,
t.relname AS table_name,
pg_index.indisunique AS is_unique,
pg_index.indisprimary AS is_primary
FROM
pg_index
JOIN pg_class c ON c.oid = pg_index.indexrelid
JOIN pg_class t ON t.oid = pg_index.indrelid
JOIN pg_namespace n ON n.oid = t.relnamespace
WHERE
n.nspname = 'public'
AND NOT pg_index.indisunique
AND NOT pg_index.indisprimary;


-- Join to pg_constraint
-- to exclude foreign key constraint indexes
SELECT
n.nspname AS schema_name,
c.relname AS index_name,
t.relname AS table_name
FROM
pg_index
JOIN
pg_class c ON c.oid = pg_index.indexrelid
JOIN
pg_class t ON t.oid = pg_index.indrelid
JOIN
pg_namespace n ON n.oid = t.relnamespace
LEFT JOIN
pg_constraint con ON con.conindid = pg_index.indexrelid
WHERE
n.nspname = 'public'
AND NOT pg_index.indisprimary
AND con.contype IS NULL; -- Excludes indexes associated with constraints


-- Find foreign key indexes
-- Credit: https://mohyusufz.medium.com/how-to-check-for-indexes-on-foreign-key-columns-in-postgresql-450159772f8e
WITH fk_constraints AS (
SELECT
c.conrelid::regclass AS table,
c.conname AS constraint,
string_agg(a.attname, ',' ORDER BY x.n) AS columns,
pg_catalog.pg_size_pretty(pg_catalog.pg_relation_size(c.conrelid)) AS size,
c.confrelid::regclass AS referenced_table,
c.conkey AS conkey,
c.conrelid AS conrelid
FROM
pg_catalog.pg_constraint c
/* Enumerated key column numbers per foreign key */
CROSS JOIN LATERAL unnest(c.conkey)
WITH ORDINALITY AS x (attnum, n)
/* Join to get the column names */
JOIN pg_catalog.pg_attribute a ON a.attnum = x.attnum
AND a.attrelid = c.conrelid
WHERE
/* Ensure the constraint is a foreign key */
c.contype = 'f'
GROUP BY
c.conrelid,
c.conname,
c.confrelid,
c.conkey
)
SELECT
fk.table,
fk.constraint,
fk.columns,
fk.size,
fk.referenced_table,
/* Retrieve the index name or mark as Unindexed */
COALESCE((
SELECT
i.indexrelid::regclass::text
FROM pg_catalog.pg_index i
WHERE
i.indrelid = fk.conrelid
AND i.indpred IS NULL
AND (i.indkey::smallint[])[0:cardinality(fk.conkey) - 1] OPERATOR (pg_catalog. @>) fk.conkey LIMIT 1), 'Unindexed') AS index_name
FROM
fk_constraints fk
ORDER BY
pg_catalog.pg_relation_size(fk.conrelid) DESC;