请问@ManyToOne默认是否创建索引?为何H2自动建而PostgreSQL不建?
结论
JPA规范本身没有要求@ManyToOne关联注解默认给对应字段创建索引,该自动创建行为完全由ORM实现(通常为Hibernate)和所配置的数据库方言决定。
不同环境表现差异的原因
- 本地H2环境:你使用的
FixedH2Dialect是JHipster定制的H2适配方言,为了降低开发阶段关联查询性能问题的排查成本,默认会为所有外键关联字段自动创建索引,这是轻量开发类数据库的常见适配逻辑。 - UAT Postgres环境:你使用的
FixedPostgreSQL10Dialect遵循PostgreSQL本身的默认设计逻辑:创建外键约束时不会自动生成对应索引,需要开发者手动显式声明,因此不会自动生成关联字段的索引。
最佳实践
不要依赖不同方言的隐性行为来创建索引,如果你确认该关联字段需要索引以优化关联查询性能,直接在实体类的@Table注解中显式声明即可,示例如下:
@Entity @Table(name = "user", indexes = { // 显式声明reg字段的索引 @Index(name = "idx_user_reg_id", columnList = "reg_id") }) public class User extends BaseAudit implements Serializable { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator") @SequenceGenerator(name = "sequenceGenerator") private Long id; @ManyToOne @JoinColumn(referencedColumnName = "id") @JsonIgnoreProperties(value = { "userList" }) private Reg reg; }
补充说明
PostgreSQL默认不为外键自动创建索引是合理设计:如果外键字段很少作为查询条件、也不会频繁用于关联查询,额外的索引反而会增加数据写入时的开销,因此官方将索引创建的选择权交给了开发者,方便根据实际业务场景调整。
内容的提问来源于stack exchange,提问作者sophie
相关产品推荐
相关产品推荐

