SQL

Détecter les clés étrangères sans index

PostgreSQL n'indexe pas automatiquement les FK : chaque DELETE sur le parent déclenche alors un seq scan de l'enfant. Cette requête catalogue liste les FK dont la première colonne n'est indexée nulle part.

Cas d'usage

DELETE parent anormalement lents, deadlocks sur des chaînes de FK non indexées.

Prérequis

PostgreSQL (catalogues pg_constraint / pg_index)

SQL
SELECT
    c.conrelid::regclass        AS table_name,
    c.conname                   AS fk_name,
    string_agg(a.attname, ', ') AS fk_columns
FROM pg_constraint c
JOIN pg_attribute a
  ON a.attrelid = c.conrelid AND a.attnum = ANY (c.conkey)
WHERE c.contype = 'f'
  AND NOT EXISTS (
      SELECT 1
      FROM pg_index i
      WHERE i.indrelid = c.conrelid
        AND i.indkey[0] = c.conkey[1]   -- 1re colonne de l'index = 1re de la FK
  )
GROUP BY c.conrelid, c.conname
ORDER BY table_name;

Résultat

 table_name  |          fk_name          | fk_columns
-------------+---------------------------+-------------
 order_items | order_items_order_id_fkey | order_id
 payments    | payments_invoice_id_fkey  | invoice_id
 shipments   | shipments_order_id_fkey   | order_id
(3 rows)   -- 3 FK sans index : DELETE parent = seq scan enfant
SQLForeign KeyIndexCatalogue

Snippets liés

Retour au Data Lab