[sql] Postgres and Indexes on Foreign Keys and Primary Keys

This function, based on the work by Laurenz Albe at https://www.cybertec-postgresql.com/en/index-your-foreign-key/, list all the foreign keys with missing indexes. The size of the table is shown, as for small tables the scanning performance could be superior to the index one.

--
-- function:    fkeys_missing_indexes
-- purpose:     list all foreing keys in the database without and index in the source table.
-- author:      Laurenz Albe
-- see:         https://www.cybertec-postgresql.com/en/index-your-foreign-key/
--
create or replace function oftool_fkey_missing_indexes () 
returns table (
  src_table     regclass,
  fk_columns    varchar,
  table_size    varchar,
  fk_constraint name,
  dst_table     regclass
)
as $$
select
  -- source table having ta foreign key declaration
  tc.conrelid::regclass as src_table,
  
  -- ordered list of foreign key columns
  string_agg(ta.attname, ',' order by tx.n) as fk_columns,
  
  -- source table size
  pg_catalog.pg_size_pretty (
    pg_catalog.pg_relation_size(tc.conrelid)
  ) as table_size,
  
  -- name of the foreign key constraint
  tc.conname as fk_constraint,
  
  -- name of the target or destination table
  tc.confrelid::regclass as dst_table
  
from pg_catalog.pg_constraint tc

-- enumerated key column numbers per foreign key
cross join lateral unnest(tc.conkey) with ordinality as tx(attnum, n)

-- name for each key column
join pg_catalog.pg_attribute ta on ta.attnum = tx.attnum and ta.attrelid = tc.conrelid

where not exists (
  -- is there ta matching index for the constraint?
  select 1 from pg_catalog.pg_index i
  where 
    i.indrelid = tc.conrelid and 
    -- the first index columns must be the same as the key columns, but order doesn't matter
    (i.indkey::smallint[])[0:cardinality(tc.conkey)-1] @> tc.conkey) and 
    tc.contype = 'f'
  group by 
    tc.conrelid, 
    tc.conname, 
    tc.confrelid
  order by 
    pg_catalog.pg_relation_size(tc.conrelid) desc;
$$ language sql;

test it this way,

select * from oftool_fkey_missing_indexes();

you'll see a list like this.

fk_columns            |table_size|fk_constraint                     |dst_table        |
----------------------|----------|----------------------------------|-----------------|
id_group              |0 bytes   |fk_customer__group                |im_group         |
id_product            |0 bytes   |fk_cart_item__product             |im_store_product |
id_tax                |0 bytes   |fk_order_tax_resume__tax          |im_tax           |
id_product            |0 bytes   |fk_order_item__product            |im_store_product |
id_tax                |0 bytes   |fk_invoice_tax_resume__tax        |im_tax           |
id_product            |0 bytes   |fk_invoice_item__product          |im_store_product |
id_article,locale_code|0 bytes   |im_article_comment_id_article_fkey|im_article_locale|

Examples related to sql

Passing multiple values for same variable in stored procedure SQL permissions for roles Generic XSLT Search and Replace template Access And/Or exclusions Pyspark: Filter dataframe based on multiple conditions Subtracting 1 day from a timestamp date PYODBC--Data source name not found and no default driver specified select rows in sql with latest date for each ID repeated multiple times ALTER TABLE DROP COLUMN failed because one or more objects access this column Create Local SQL Server database

Examples related to database

Implement specialization in ER diagram phpMyAdmin - Error > Incorrect format parameter? Authentication plugin 'caching_sha2_password' cannot be loaded Room - Schema export directory is not provided to the annotation processor so we cannot export the schema SQL Query Where Date = Today Minus 7 Days MySQL Error: : 'Access denied for user 'root'@'localhost' SQL Server date format yyyymmdd How to create a foreign key in phpmyadmin WooCommerce: Finding the products in database TypeError: tuple indices must be integers, not str

Examples related to postgresql

Subtracting 1 day from a timestamp date pgadmin4 : postgresql application server could not be contacted. Psql could not connect to server: No such file or directory, 5432 error? How to persist data in a dockerized postgres database using volumes input file appears to be a text format dump. Please use psql Postgres: check if array field contains value? Add timestamp column with default NOW() for new rows only Can't connect to Postgresql on port 5432 How to insert current datetime in postgresql insert query Connecting to Postgresql in a docker container from outside

Examples related to foreign-keys

Migration: Cannot add foreign key constraint The ALTER TABLE statement conflicted with the FOREIGN KEY constraint Can a foreign key refer to a primary key in the same table? Introducing FOREIGN KEY constraint may cause cycles or multiple cascade paths - why? MySQL Error 1215: Cannot add foreign key constraint MySQL Cannot Add Foreign Key Constraint Delete rows with foreign key in PostgreSQL How to remove constraints from my MySQL table? MySQL - Cannot add or update a child row: a foreign key constraint fails How to remove foreign key constraint in sql server?