【发布时间】:2020-02-16 11:40:26
【问题描述】:
我正在使用 Google Cloud Spanner,我需要一种将行的值增加 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:Syntax error: Unexpected keyword ON)
db.transaction do |tx|
tx.batch_update do |b|
b.batch_update(
"INSERT INTO table (key, value) VALUES ('ABC', 1) ON DUPLICATE KEY UPDATE value = value + 1"
)
end
end
似乎也无法通过 Mutations 增加。这只会创建行或覆盖值:
db.transaction do |tx|
tx.upsert "test", [{ key: 'ABC', value: 1 }]
end
有什么方法可以用 Spanner 做我需要的事情吗? 与每秒 100k+ 行的批量写入性能相比,缓慢的多行解决方案真的很可悲。
【问题讨论】: