【发布时间】:2020-03-22 19:51:48
【问题描述】:
像许多 Postgres n00bs 一样,我们有很多带有未索引的外键约束的表。在某些情况下,这不应该对性能造成很大影响 - 但这需要进一步分析。
我已阅读以下文章:https://www.cybertec-postgresql.com/en/index-your-foreign-key/
并使用以下查询查找所有没有索引的外键:
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::int[])
AND c.contype = 'f'
GROUP BY c.conrelid, c.conname, c.confrelid
ORDER BY pg_catalog.pg_relation_size(c.conrelid) DESC;
这向我展示了具有复合唯一约束的表,只有唯一索引中的“一”列:
\d topics_items;
-----------------+---------+--------------+---------------+------------------------------
topics_items_id | integer | | not null | generated always as identity
topic_id | integer | | not null |
item_id | integer | | not null |
Index:
"topics_items_pkey" PRIMARY KEY, btree (topics_items_id)
"topic_id_item_id_unique" UNIQUE CONSTRAINT, btree (topic_id, item_id)
Foreign Keys:
"topics_items_item_id_fkey" FOREIGN KEY (item_id) REFERENCES items(item_id) ON DELETE CASCADE
"topics_items_topic_id_fkey" FOREIGN KEY (topic_id) REFERENCES topics(topic_id) ON DELETE CASCADE
在这种情况下,检查查询仅找到 item_id 而不是 topic_id 作为未索引字段。
公平地说,这只是所使用查询的问题,我必须分别索引两个字段(topic_id 和 item_id) - 或者是否涉及一些黑色巫术,只有 item_id 需要索引?
【问题讨论】:
标签: sql postgresql indexing query-performance