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

如何优化文件查询性能?能否将两次查询合并为单次请求?

合并两次数据库查询以提升性能的实现方案

当然可行,将两次查询合并为单次能减少数据库IO操作,有效提升接口性能。以下提供两种适配你需求的实现方案:

方案一:数据库层面完成排序(推荐)

通过调整查询的排序规则,让数据库直接返回「目录按字母升序排列在前,非目录按字母升序排列在后」的结果,无需在代码中额外处理分组与合并。

@Get('roots')
async findRoots(@Req() request: Request) {
  const user = await this.authService.findCurrentUser(request);
  const allFiles = await this.fileService.findAll({
    relations: ['user', 'parent', 'parent.parent'],
    order: [
      // 强制目录排在最前面,不受字符串默认排序影响
      Raw(alias => `CASE WHEN ${alias}.type = 'dir' THEN 0 ELSE 1 END`),
      // 同类型内按名称字母升序排序
      { name: 'ASC' },
    ],
    where: {
      user: user.user_id,
      parent: IsNull(),
    },
  });
  return allFiles;
}

补充说明

  • 若你的type字段是枚举类型,且dir在枚举中的定义顺序本身靠前,可将Raw语句替换为{ type: 'ASC' },简化排序逻辑。
  • 数据库层面排序能利用索引优化,数据量越大,相比内存排序的性能优势越明显。

方案二:内存中分组排序

一次性查询所有符合条件的文件,再在代码中过滤出目录和非目录,分别排序后合并。该方案无需依赖数据库排序逻辑,适合数据量较小的场景。

@Get('roots')
async findRoots(@Req() request: Request) {
  const user = await this.authService.findCurrentUser(request);
  const allFiles = await this.fileService.findAll({
    relations: ['user', 'parent', 'parent.parent'],
    where: {
      user: user.user_id,
      parent: IsNull(),
    },
  });

  // 过滤并排序目录
  const directories = allFiles
    .filter(file => file.type === 'dir')
    .sort((a, b) => a.name.localeCompare(b.name));
  
  // 过滤并排序非目录文件
  const otherFiles = allFiles
    .filter(file => file.type !== 'dir')
    .sort((a, b) => a.name.localeCompare(b.name));

  return directories.concat(otherFiles);
}

注意事项

  • 两种方案均只发起一次数据库请求,相比原代码减少了一次IO开销。
  • 若使用方案二,需注意localeCompare的区域设置,确保字母排序符合业务预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 10:42:40