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

如何让Directus在PostgreSQL子表创建项时执行BULK INSERT优化性能

解决Directus子表批量创建时的单条INSERT性能问题

针对你提到的Directus处理子表items.create时逐个执行INSERT导致的性能瓶颈,以下是几个可行的优化方案:

1. 改用Directus批量创建API接口

Directus原生支持批量创建条目,无需额外扩展。你只需要调整API调用方式:

  • 原本单次调用POST /items/your_child_collection传入单个对象,现在改为传入对象数组
  • 示例请求体:
    [
      {"session_id": "sess_001", "value": "foo"},
      {"session_id": "sess_001", "value": "bar"},
      {"session_id": "sess_001", "value": "baz"}
    ]
    
  • 这样Directus会自动生成PostgreSQL的BULK INSERT语句,而非逐条执行INSERT

如果是通过工作流触发的创建逻辑,需要修改工作流:不要循环调用单条创建接口,而是先收集所有待插入的数据,最后一次性调用批量接口。

2. 自定义Hook实现底层批量插入

如果工作流或业务逻辑无法直接改用批量API,可以通过Directus的自定义Hook拦截创建请求,手动执行批量插入:

  • 创建一个items.create的before hook,判断传入的是否为批量数据(或主动收集批量数据)
  • 使用Directus内置的Knex客户端执行批量插入,示例代码:
    export default defineHook(({ action, database }) => {
      action('items.create', async (payload, meta) => {
        // 仅针对目标子表执行逻辑
        if (meta.collection !== 'sessions_child') return;
    
        // 处理批量数据(如果payload是数组)
        const rows = Array.isArray(payload) ? payload : [payload];
        
        // 执行批量插入
        await database.insert(rows).into('sessions_child');
        
        // 跳过Directus默认的单条插入逻辑
        return { skipDefault: true };
      });
    });
    
  • 注意:需要确保Hook的权限足够,同时处理事务和字段验证逻辑,避免数据不一致。

3. 数据库层面辅助优化

除了Directus端的调整,还可以优化PostgreSQL配置提升批量插入性能:

  • 批量插入期间临时关闭autovacuum(插入完成后恢复)
  • 调整work_mem和maintenance_work_mem参数,提升内存分配
  • 批量插入前禁用目标表的非必要索引,插入完成后重新创建(如果业务允许短暂的索引不可用)

关键注意事项

  • 批量操作必须包裹在事务中,确保数据原子性
  • 验证所有待插入数据符合Directus的字段规则(必填项、数据类型等)
  • 确保调用批量接口的用户拥有目标子表的创建权限

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 22:55:09