PostgreSQL外键是否自动创建索引?复合外键场景咨询
嘿,这个问题抓得很准!我来给你拆解清楚:
PostgreSQL不会自动为复合外键创建索引
这是个很容易踩的坑——PostgreSQL创建外键的核心目的是保证引用完整性(比如阻止你插入Logs表中不存在的关联记录,或者处理删除/更新时的级联操作),而不是自动优化查询性能。所以默认情况下,你的Events表不会因为这个复合外键而自动生成对应的索引。无关联的查询无法直接受益于外键
如果你有单独针对Events表中外键字段的查询(比如SELECT * FROM Events WHERE log_col1 = 'foo' AND log_col2 = 'bar'),没有手动创建索引的话,PostgreSQL只能做全表扫描(Seq Scan),完全没法利用外键来加速。只有当你手动创建了匹配外键字段顺序(或查询过滤顺序)的复合索引,这类查询才能享受到索引带来的性能提升。举个例子,你可以这样创建索引:CREATE INDEX idx_events_log_fk ON Events (log_col1, log_col2);关联查询的索引依赖
你提到的“通过主键高效查询Events并关联Logs”,这种场景下受益的是Logs表的主键索引(因为你是从Events的主键找到记录,再关联Logs的主键)。但反过来,如果是从Logs关联查询Events,Events这边没有外键索引的话,性能可能会打折扣——这时候PostgreSQL可能需要遍历Events表来匹配关联条件。
另外,你提到已经跑了EXPLAIN,可以留意执行计划里的关键字:如果针对外键字段的查询出现Seq Scan,就说明没有对应的索引;如果是Index Scan/Index Only Scan,那说明存在可用的索引(要么是你手动建的,要么是其他业务场景下创建的索引刚好匹配)。
内容的提问来源于stack exchange,提问作者Mark Shamis

