Google cloud spanner 谷歌云扳手中的增量值

Google cloud spanner 谷歌云扳手中的增量值,google-cloud-spanner,Google Cloud Spanner,我正在使用GoogleCloud扳手,我需要一种方法将行的值增加value=value+1。 这是一个非常令人头痛的问题,因为我看不到检查行是否已经存在的方法。 我正在使用Ruby客户端库(gem版本1.13.1) 目前,我有以下代码来完成这项工作,但速度仅为每秒40-50个事务。 我看不到批处理的方法,因为据我所知,我只能批处理单个DML语句 db.transaction do |transaction| if transaction.execute_query("SELECT value

我正在使用GoogleCloud扳手,我需要一种方法将行的值增加
value=value+1
。 这是一个非常令人头痛的问题,因为我看不到检查行是否已经存在的方法。 我正在使用Ruby客户端库(gem版本1.13.1)

目前,我有以下代码来完成这项工作,但速度仅为每秒40-50个事务。 我看不到批处理的方法,因为据我所知,我只能批处理单个DML语句

db.transaction do |transaction|
  if transaction.execute_query("SELECT value FROM table WHERE key = 'ABC'").rows.first.to_h[:value]
    transaction.execute_update("UPDATE table SET value = value + 1 WHERE key = 'ABC'")
  else
    transaction.execute_update("INSERT INTO table (key, value) VALUES ('ABC', 1)")
  end
end
不幸的是,用一条语句解决这个问题的SQL似乎根本不受支持。(我得到的是
Google::Cloud::InvalidArgumentError(3:语法错误:在
上出现意外的关键字)

似乎也不可能通过突变增加。这只会创建行或覆盖值:

db.transaction do |tx|
  tx.upsert "test", [{ key: 'ABC', value: 1 }]
end
有什么办法可以用扳手来做我需要的事情吗?
与每秒100k+行的批处理写入性能相比,慢速多行解决方案真的很糟糕。

没有一种简单的方法来完成您需要的任务

为确保我们获得合理的吞吐量,需要探索的一个选项是:

  • 读取所有要更新或插入的密钥
  • 构造一个BatchDML,其中包含一组基于结果的insert/update语句 读取步骤1
  • 请注意,更新必须是有条件的更新。 示例:“更新表集合值={prev_value}+1其中key=“ABC” 和值={prev_value}”
  • 执行构造的BatchDML。请注意,某些语句可能会失败

    如果密钥已经存在,插入可能会失败:我相信这不应该是一个问题,因为密钥存在(这是插入尝试所期望的结果)

    如果值在读取时发生更改,则更新可能不会发生。如果重复此循环,则更新可能会在下一批中发生


  • 正如您所看到的,这需要注意。

    没有一种简单的方法来完成您所需要的

    为确保我们获得合理的吞吐量,需要探索的一个选项是:

  • 读取所有要更新或插入的密钥
  • 构造一个BatchDML,其中包含一组基于结果的insert/update语句 读取步骤1
  • 请注意,更新必须是有条件的更新。 示例:“更新表集合值={prev_value}+1其中key=“ABC” 和值={prev_value}”
  • 执行构造的BatchDML。请注意,某些语句可能会失败

    如果密钥已经存在,插入可能会失败:我相信这不应该是一个问题,因为密钥存在(这是插入尝试所期望的结果)

    如果值在读取时发生更改,则更新可能不会发生。如果重复此循环,则更新可能会在下一批中发生

  • 正如你所看到的,这需要注意

    db.transaction do |tx|
      tx.upsert "test", [{ key: 'ABC', value: 1 }]
    end