批量插入优化
“批量插入”优化的关键在于能够将多个“插入”和“插入或更新”语句组合成单个 RSQL 传输。
该优化允许将插入语句参数数组传递到单个 executeStatement("INSERT INTO...")
调用中。 假设应用程序需要向数据库添加十个对象。直接实现这一操作的方式如以下代码片段所示:
for (int i = 0; i < 10; i++)
{
// 设置语句的参数
int4 key = i;
int4 value = key + 10;
// 执行
engine->executeStatement("insert into Record (id, value) values(%i %i)", key, value);
}
“批量插入”通过单个“执行”来实现相同的操作。多个插入操作符的参数被“打包”,然后传递给 execute()
函数:
// 创建参数数组
Array* key_array = Array::create(engine->getAllocator(), tpInt4, 0, 10);
Array* value_array = Array::create(engine->getAllocator(), tpInt4, 0, 10);
for (int i = 0; i < 10; i++)
{
// 设置语句的参数
int4 key = i;
int4 value = key + 10;
// 将每个语句的参数写入数组中
key_array->setAt(array_idx, IntValue::create(engine->getAllocator(), key));
value_array->setAt(array_idx, IntValue::create(engine->getAllocator(), value));
}
// 调用一次“execute”
// 在内部使用来自 key_array 和 value_array 的参数执行 10 次“插入到 Record”
engine->executeStatement("insert into Record (id, value) values(%v, %v)", key_array, value_array);
// 释放由数组及其内容分配的内存空间
DELETE_OBJ(engine->getAllocator(), key_array);
DELETE_OBJ(engine->getAllocator(), value_array);
批量插入操作可在本地执行,也可通过远程 SQL 协议执行。在远程 SQL 执行下,性能提升非常显著。
此外,除了 INSERT
操作外,批量插入优化还可用于 INSERT OR UPDATE
操作符。例如:
Array* key_array = Array::create(engine->getAllocator(), tpInt4, 0, 10);
Array* value_array = Array::create(engine->getAllocator(), tpInt4, 0, 10);
for (int i = 0; i < 10; i++)
{
int4 key = i;
int4 value = key + 10;
key_array->setAt(array_idx, IntValue::create(engine->getAllocator(), key));
value_array->setAt(array_idx, IntValue::create(engine->getAllocator(), value));
}
engine->executeStatement("insert or update into Record (id, value) values(%v, %v)", key_array, value_array);
DELETE_OBJ(engine->getAllocator(), key_array);
DELETE_OBJ(engine->getAllocator(), value_array);
请注意,INSERT OR UPDATE
需要在被修改的表上有一个唯一索引,并允许在键与新值匹配时更新对象。
请参阅SDK 示例 samples/native/sql/api/sql-14-perf 以了解“批量插入”的使用及上述性能改进。