假设我们有一个MySQL后端,其中有一个表的主键是用UNIQUE属性定义的。我们从多个分布式系统接收数据,所有这些系统都具有相同/相似的实现。
在某些时候,我们将尝试批量插入例如 1000 万个文档行,但我们只想在不违反唯一约束的情况下存储数据,哪种方法会更快/被认为是可以的..?
例如
try {
//...try and insert the document
} catch(MySQLIntegrityConstraintViolationException e) {
//..do nothing, since this is already stored in the database
//move on to the next one..
}
或
//we try to find the document...
if(!documentFound) {
//we did not find a document with this id, so we can safely insert it..
//move on to the next one...
}
在我的脑海中,我猜测在这两种情况下,我们尝试插入的id都必须"找到",因为我们必须验证唯一约束,但是两者中的哪一个被认为与其速度有关或多或少是好的?
附带问题:答案/结果(例如速度方面)是否相同,例如 Mysql 与 mongoDB 的关系?
您不能只使用插入..重复。这样你就不必担心它们是否已经存在?所以在你的情况下你可以做
ON DUPLICATE KEY UPDATE id=id
一般来说,我会保留例外...特殊情况:)换句话说,如果正常工作流程中可能发生某些事情,我宁愿以常规if
来处理这种情况。空的catch
子句通常表示有问题。
另外,我宁愿使用 INSERT IGNORE
结构(而不是ON DUPLICATE
- 它工作得很好,但我不喜欢黑客UPDATE id=id
)。
如果使用 IGNORE 关键字,则会忽略执行 INSERT 语句时发生的错误。(...)忽略的错误可能会生成警告,但重复键错误不会。
如果您坚持循环访问记录并逐个处理它们,我会建议另一种方法
伪代码
- 创建哈希列表
- 在哈希列表中搜索唯一键
- 如果未找到,请插入到数据库中。将唯一键添加到哈希列表
- 获取下一条记录
- 转到 2 如果不是 eof。
如果有很多重复项,则可以节省大量(相对)昂贵的数据库调用。