防止重复最有效

Luc*_*man 5 postgresql

我正在构建一个应用程序,它将每隔一段时间使用 JSON 获取消息并将这些消息存储在 postgres 数据库中。现在我想防止重复,所以我计算了消息的 sha-512 并将其设置为主键。由于我想防止重复,我可以做两件事:

  1. 从数据库中获取所有散列,并查看何时插入新消息,如果散列已经存在(检查代码)
  2. 使用插入忽略(在 postgres 中可能是更新,因为 postgres 不支持插入忽略)并让数据库处理这些异常

考虑到我可能会一次插入几条消息,我想知道方法 2 是否会查找主键并查看每个插入是否存在,而不是仅使用方法 1 在内存中存储一​​个列表。什么是最多的高效的?

Cra*_*ger 6

PostgreSQL 没有,INSERT ... IGNORE所以这不是一个选项。您可以使用类似 upsert 的操作(搜索“postgresql upsert),但它们肯定会有性能成本。插入和忽略重复键上产生的错误是可能的,但它往往会导致非常垃圾的日志。

就我个人而言,我会做有效地进行批量更新的事情,在那里我会做这样的事情:

  • CREATE TEMPORARY TABLE staging_table(...)
  • COPY TO staging_table(...) FROM ... (或进行批量插入)
  • LOCK TABLE real_table IN EXCLUSIVE MODE
  • INSERT INTO real_table(...) SELECT col1,col2,col3,... FROM staging_table WHERE NOT EXISTS (SELECT 1 FROM real_table WHERE real_table.primarykey = staging_table.primarykey)
  • COMMIT

如果需要,您可以在UPDATE之前执行INSERT,使用新值更新现有记录。

LOCK TABLE是防止并发更新因错误而失败所必需的。您仍然可以SELECT在更新期间从表中获取。

如果您EXPLAIN为您的计划制定了计划,您INSERT应该看到它JOIN在您插入大量记录时已转换为 a 。