【问题标题】:Performance during searching data in DB vs Memory [closed]在数据库与内存中搜索数据时的性能[关闭]
【发布时间】:2017-12-25 19:20:04
【问题描述】:

我目前正在使用 PostgreSQL 数据库、Spring 和 Hibernate。我有一张表,其中属性correlation_id 是唯一的。每次在我首先添加一个新元素之前,我都必须检查数据库中是否已经存在任何具有新相关 ID 的项目。

对于这种情况,我已经实现了递归函数,它将生成一个新的 correlation_id 并检查它在 db 中是否存在。这意味着这个函数每次都会在 db 上进行调用,所以有时它可能只是一个调用,但有时我可能是五个、十个甚至更多。此示例如示例一所示。

示例 1:

private String generateId() {

    String myId = StaticFunction.generateMyId();
    MyMessages doesExist = MyServiceDaoImpl.checkDoesItExistInDB(myId);
    if(doesExist != null) {
        generateId();
    }

    return myId;
}

在第二个示例中,我假设我可以只创建一个对 db 的调用并检索所有项目并将它们放入集合中。然后我可以通过流来搜索使用递归函数的特定项目。 例 2:

private String generateId(List<MyMessages> messages) {
    String myId = StaticFunction.generateMyId();        

    MyMessages myMessage = messages.stream().filter(m -> 
        m.getCorrelationId.equals(myId)).findFirst().orElse(null);
    if (MyMessages != null) {
        generateId(messages);
    }

    return myId;
}

我的问题是使这件事正确的最佳方法是什么?您还有其他解决方案吗?以上例子的优缺点是什么?

【问题讨论】:

  • 为什么不用db生成的id
  • 第三个选项就是插入任何重复键并失败
  • @ScaryWombat 我不使用生成的 id,因为某种原因,correlation_id 有时可能为空,而且我还需要一些项目包含相关 ID 的空
  • 如果你有另一个id和correlation_id,你可以选择是否将唯一值从id复制到correlation_id
  • 另一个取决于您的负载的选项是将当前时间用作毫秒

标签: java spring postgresql performance hibernate


【解决方案1】:

如果您不能按照 cmets 中的建议使用 db 生成的 id,您可以使用 UUID 生成器来创建 PK。碰撞的概率太低了,不值得在数据库中检查。

要在 Java 中生成 UUID,请查看 http://docs.oracle.com/javase/7/docs/api/java/util/UUID.html

【讨论】:

  • 我知道,但仍有可能两个项目包含相同的correlation_id。无论如何,使用 UUID 我可能会减少对 db 的调用。
  • 你被陨石击中的可能性比 UUID 碰撞的可能性更大
  • 哈哈是的,你是对的,但想象一下你正在制作处理金钱等的应用程序,这是不可接受的
  • uuid 是从多个参数生成的 - 节点(主机名或 ip 或 mac)、时间戳、计数器.. - 您几乎可以相信 uuid 将是唯一的,如果您点击重复项,只需重试/失败关键异常。我敢打赌 1:2^256 你会没事的..
  • 不可接受" - 然后让dataabse处理唯一键,它会确保生成的值是唯一的。
【解决方案2】:

情况1没有问题,当列被索引时,DB可以非常有效地进行查找。但是 - 您需要进行数据库访问。

第二种情况看起来要快得多(在内存中迭代将比任何数据库访问快得多),但是它有缺点:您必须将所有消息(或至少它们的相关 id)保存在内存中,并且当有很多时数据,你是scr..你将很难修复它

同时考虑应用程序的多个实例可以访问数据库的可扩展性。

因此我建议让数据库生成密钥(您可以使用例如 SERIAL 数据类型)并且 Hibernate 在保存对象时返回生成的密钥。如果您需要自定义 id(由您的应用生成),您可以在值冲突概率较低的地方使用 uuid

您也可以使用 UPSERT 语法 (INSERT .... ON CONFLICT (correlation_id) ...)

玩得开心

【讨论】:

    猜你喜欢
    • 2013-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-26
    • 1970-01-01
    • 2011-07-11
    • 2019-02-20
    • 2012-09-19
    相关资源
    最近更新 更多