什么是在Cassandra列族中插入多行的最有效方法?是否可以在单个调用中完成这个操作。
目前,我的方法是添加并插入多个列,然后执行。在单个调用中,我正在持久化一行数据。我正在寻找一个批量插入的策略。
什么是在Cassandra列族中插入多行的最有效方法?是否可以在单个调用中完成这个操作。
目前,我的方法是添加并插入多个列,然后执行。在单个调用中,我正在持久化一行数据。我正在寻找一个批量插入的策略。
CQL包含一个BEGIN BATCH...APPLY BATCH
语句,允许您将多个插入分组,以便开发人员可以创建和执行一系列请求
(请参见http://www.datastax.com/dev/blog/client-side-improvements-in-cassandra-2-0)。
以下代码在Scala中可行:
PreparedStatement ps = session.prepare(
"BEGIN BATCH" +
"INSERT INTO messages (user_id, msg_id, title, body) VALUES (?, ?, ?, ?);" +
"INSERT INTO messages (user_id, msg_id, title, body) VALUES (?, ?, ?, ?);" +
"INSERT INTO messages (user_id, msg_id, title, body) VALUES (?, ?, ?, ?);" +
"APPLY BATCH" );
session.execute(ps.bind(uid, mid1, title1, body1, uid, mid2, title2, body2, uid, mid3, title3, body3));
如果您事先不知道要执行哪些语句,您可以使用以下语法(Scala):
var statement: PreparedStatement = session.prepare("INSERT INTO people (name,age) VALUES (?,?)")
var boundStatement = new BoundStatement(statement)
val batchStmt = new BatchStatement()
batchStmt.add(boundStatement.bind("User A", "10"))
batchStmt.add(boundStatement.bind("User B", "12"))
session.execute(batchStmt)
注意: BatchStatement
只能容纳最多 65536 条语句。我通过艰难的经历学会了这一点。 :-)
var
都应该是val
。对象引用不会改变。 - mlgboundStatement.bind(...)
替换为 new BoundStatement(statement).bind(...)
。 - oseiskarHFactory.createMutator
然后使用返回的 Mutator 上的 add
方法添加操作到您的批处理中。当准备好时,调用 execute()
。BEGIN BATCH
开始批处理并使用 APPLY BATCH
结束来将内容分组到批处理中。当尝试插入多行数据时,数据库连接的往返时间可能成为性能瓶颈。在这种情况下,我们通常需要一种方式来避免等待一个INSERT
完成,以便我们可以开始下一个INSERT
。目前据我所知有两种方法:
LOGGED BATCH
,但是如this question所说,BATCH
并不一定在所有情况下都能提高性能。execute_async
方法。此外,您可以在执行SQL语句之前准备好该语句。我还没有测试过准备语句与普通插入的整体性能。但我认为,如果有数千个INSERT
或更多,则应该获得性能提升。