我正在开发一项高负载服务,其中我从 kafka 接收批量消息(一次大约 500 条)。这些消息代表数据库中的实体。为了简化起见,让我们想象一下实体 A:
create table A (
id varchar references B(id),
serial_num varchar,
is_actual boolean
)
id 和序列号的组合是唯一的。
因此,当从kafka收到消息数组时 - 我将这些消息解析为实体,然后我需要通过id和serial_num检查表A中是否已经存在这样的实体,如果不存在,那么我需要更新所有通过 id 查找实体并将 is_actual 设置为 false,否则不执行任何操作。更新后 - 我需要插入新实体。因此,为了更新和插入,我使用 Spring Jdbc Template
butchUpdate()
方法。但如何以最有效的方式检查实体是否存在呢?如果我将它们一一检查 - 那么我就失去了从 kafka 获取批量消息的优势。
所以你要优化的部分是查询。
只需构建一个带有巨大 WHERE 子句的 SQL 查询,即可同时测试许多键。
伪代码:
// some pojo / record that represents the key:
record Key(String id, String serial)
List<Key> keys = ...
StringBuilder sql = new StringBuilder("")
for(key in keys) { // don't need key just need iterate keys.size times
if(!sql.isEmpty()) sql.append(" OR ")
sql.append("(id=? and serial_num=?)")
}
sql.insert(0, "Select id, serial_num from A where ")
Object[] args = flatten keys so args are keys[0].id, keys[0].serial, keys[1].id, keys[1].serial, ...
List<Key> keysInDb = jdbcTemplate.query(sql.toString, RowMapper<T> rowMapper, args)
List<key> missingKeys = keys.removeAll(keysInDb)
并且不要忘记在
(id, serial_num)
列上添加索引。