外鍵列不強制要求創建索引,但強烈建議創建。 兩者是獨立的數據庫對象,服務於不同目的:
當父表執行 DELETE 或 UPDATE 主鍵 時,數據庫必須檢查子表是否存在引用行。無索引時,需全表掃描子表並加排他鎖(TX 鎖),導致嚴重並發阻塞。有索引則可快速定位相關行,僅鎖定少量記錄。
典型場景:SELECT * FROM parent p JOIN child c ON p.id = c.parent_id。子表 parent_id 有索引時,優化器可選擇 Nested Loop Join,大幅提升性能。
Oracle、PostgreSQL、MySQL (InnoDB) 行為不同:
業務邏輯層保證完整性,數據庫僅建索引加速查詢:
-- Oracle 查詢無索引外鍵
SELECT c.table_name, c.constraint_name, c.column_name
FROM user_cons_columns c
JOIN user_constraints m ON c.constraint_name = m.constraint_name
WHERE m.constraint_type = 'R'
MINUS
SELECT table_name, index_name, column_name
FROM user_ind_columns;
索引與外鍵是「加速器」與「守門人」的關係。**外鍵列加索引不是為了查詢,而是為了讓外鍵約束本身高效運行**。理解這一點,才能在設計時做出正確取捨。