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

upsert!以非分区键为更新键时跨分区执行插入而非更新

问题解答

1. upsert!的分区行为

是的,upsert!在分区表上仅会在新行所属的目标分区内查找匹配的key行。这是因为DolphinDB的分区表设计为分区独立操作,原生upsert!会根据新行的分区键(这里是update)定位到对应分区,仅在该分区内执行更新/插入逻辑,不会遍历其他分区。这就是为什么当新行和旧行id相同但update分属不同分区时,会插入新行而非更新旧行。

2. 跨分区upsert的实现方案

原生upsert!不支持通过非分区键实现跨分区upsert,但可以通过自定义逻辑模拟该行为,核心思路是先删除全表中匹配key的旧行,再插入新行:

自定义跨分区upsert函数

def crossPartitionUpsert(targetTable, newData, keyCols):
    # 提取新数据中的唯一key值
    targetKeys = newData[keyCols].distinct()
    # 查询全表中所有匹配key的旧行
    oldRecords = select * from targetTable where keyCols in targetKeys
    # 如果存在旧行则删除
    if oldRecords.size() > 0:
        targetTable.delete!(oldRecords)
    # 插入新数据
    targetTable.append!(newData)

使用示例

替换原有的upsert!调用:

crossPartitionUpsert(t, table(1 as id, 2024.01.02 as update, 200 as val), `id)
select * from t
// 输出结果:
// id=1, update=2024-01-02, val=200

3. 注意事项与优化建议

  • 性能影响:自定义方法需要跨分区查询和删除,数据量较大时性能会比原生upsert!差,因为涉及多分区扫描。
  • 分区策略调整:如果业务中频繁需要跨分区upsert,建议重新评估分区策略。例如:
    • 将id作为哈希分区键(保证同id的行在同一分区),再结合update做复合分区;
    • 如果id是全局唯一主键,考虑将id作为唯一键而非依赖分区表的upsert逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.02 03:04:53