-
Notifications
You must be signed in to change notification settings - Fork 74
Expand file tree
/
Copy pathfk_missing_index.sql
More file actions
57 lines (55 loc) · 1.68 KB
/
fk_missing_index.sql
File metadata and controls
57 lines (55 loc) · 1.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
-- Errors if FKs do not have an index
CREATE OR REPLACE FUNCTION fk_missing_index ()
RETURNS void
AS $$
DECLARE
item record;
BEGIN
FOR item IN
SELECT
c.conrelid::regclass AS "table",
/* list of key column names in order */
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.conname AS constraint,
c.confrelid::regclass AS referenced_table
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)
/* name for each key column */
JOIN pg_catalog.pg_attribute a ON a.attnum = x.attnum
AND a.attrelid = c.conrelid
WHERE
NOT EXISTS
/* is there a matching index for the constraint? */
(
SELECT
1
FROM
pg_catalog.pg_index i
WHERE
i.indrelid = c.conrelid
/* the first index columns must be the same as the
key columns, but order doesn't matter */
AND (i.indkey::smallint[])[0:cardinality(c.conkey) - 1] @> c.conkey)
AND c.contype = 'f'
GROUP BY
c.conrelid,
c.conname,
c.confrelid
ORDER BY
pg_catalog.pg_relation_size(c.conrelid) DESC LOOP
RAISE WARNING 'CREATE INDEX "idx_%_fk_%" ON "%" ("%");', item.table, item.columns, item.table, item.columns USING HINT = to_json(item);
END LOOP;
IF FOUND THEN
RAISE EXCEPTION ' We require ALL FOREIGN keys TO have an INDEX defined. ';
END IF;
END;
$$
LANGUAGE plpgsql;
SELECT
*
FROM
fk_missing_index ();