You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeORM为何执行含多OR语句的关联ID查询?性能优化求助

问题分析与解决

问题背景

使用NestJS + TypeORM + MySQL架构,通过RDS性能洞察发现一条频繁触发的低效查询,已引发性能问题:

SELECT user_auth.id AS id, user_auth.user_id AS user_id
FROM user_auth user_auth
WHERE ((user_auth.user_id = ?)
OR (user_auth.user_id = ?)
OR (user_auth.user_id = ?)
OR ...)

代码中未手动编写过该批量查询逻辑,怀疑与User和UserAuth的OneToOne关联配置有关,实体代码如下:

user-auth.entity.ts

@Field(() => User)
@OneToOne(() => User, (user) => user.auth, {
  createForeignKeyConstraints: false,
})
@JoinColumn({ name: 'user_id' })
user: User;

@Field(() => ID)
@RelationId((userAuth: UserAuth) => userAuth.user)
userId: number;

user.entity.ts

@Field(() => UserAuth, {
  nullable: true,
})
@OneToOne(() => UserAuth, (userAuth) => userAuth.user)
auth: UserAuth;

@Field(() => ID)
@RelationId((user: User) => user.auth)
authId: number;

触发原因

这条查询是TypeORM自动生成的,根源在于User实体中的@RelationId((user) => user.auth):

  • 当查询多个User实体(比如find()、findAndCount()等批量操作)时,TypeORM会自动执行这条批量查询,用来获取每个User对应的authId值
  • 生成多个OR条件而非IN,可能是TypeORM版本特性或关联配置细节导致,但本质是为了批量匹配user_id,获取对应的user_auth.id作为authId

性能优化方案

1. 添加索引(最紧急)

针对user_auth表的user_id字段添加索引,直接解决查询性能瓶颈:

CREATE INDEX idx_user_auth_user_id ON user_auth(user_id);

该索引会让MySQL快速定位匹配的user_id记录,大幅降低查询延迟和等待负载。

2. 优化关联加载逻辑

避免TypeORM自动生成批量查询,改为手动关联查询:
在查询User时,手动关联user_auth并直接获取authId,替代@RelationId的自动加载:

// 示例:UserService中的查询方法
async getUsers() {
  return this.userRepository.createQueryBuilder('user')
    .leftJoin('user.auth', 'auth')
    .select([
      'user.id',
      'user.username', // 按需添加其他User字段
      'auth.id as authId' // 手动指定authId
    ])
    .getMany();
}

同时可考虑移除User实体中的@RelationId字段,避免自动触发查询。

3. 调整TypeORM关联配置

如果需要保留@RelationId,检查是否开启了eager自动加载(若开启会强制自动关联查询),必要时关闭:

// 修改User实体的auth关联配置
@OneToOne(() => UserAuth, (userAuth) => userAuth.user, { eager: false })
auth: UserAuth;

4. 升级TypeORM版本

部分旧版TypeORM在处理批量@RelationId查询时,会生成低效的OR语句而非IN,升级到最新稳定版(如0.3.x系列)可能会自动优化为IN条件,提升查询效率。

内容的提问来源于stack exchange,提问作者Woojin Lee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 15:22:36