在DB与内存中搜索数据时的性能

时间:2017-07-20 08:02:40

标签: java spring postgresql performance hibernate

我目前正在使用PostgreSQL数据库,Spring和Hibernate。我有一个表属性correlation_id是唯一的。每次我添加一个新元素之前,我必须检查db中是否已存在任何具有新correlation_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;
}

我的问题是什么是使这件事情做对的最佳方法?你有其他解决方案吗?上述例子有哪些优点和缺点?

2 个答案:

答案 0 :(得分:1)

如果你不能像评论中所建议的那样使用db generated id,你可以使用UUID生成器来创建PK。碰撞的概率非常低,不值得在db中检查。

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

答案 1 :(得分:0)

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

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

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

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

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

玩得开心