Я использую 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
Это также не представляется возможным увеличить с помощью мутаций. Это просто создаст строку или перезапишет значение:
db.transaction do |tx|
tx.upsert "test", [{ key: 'ABC', value: 1 }]
end
Есть ли способ сделать то, что мне нужно, с помощью Spanner вообще? Медленное многорядное решение действительно печально по сравнению с производительностью пакетной записи со скоростью 100 000 строк в секунду.