每次使用查找地图要比每次从数据库加载慢?怎么会来?

时间:2019-05-02 21:55:41

标签: java mysql hibernate

我面临一个问题。现在,我看到我们的旧代码有一个批处理插入。在此之前,该代码进行了大量验证。但是,我认为可以改进的一件事是在遗留代码中,每次我们尝试从DB加载数据并查看其是否存在时。我以为可以在第一时间(第一项)将所有表数据加载到并发的哈希图中,但是只需检查映射中的记录即可。这是代码。

private ConcurrentMap<String, Integer> name2IdMap;

........

public Integer fetchIdByName(String name) {
        if (name2IdMap == null) {
            List<Entity> entities = dao.listAll();
            Map<String, Integer> temp = entities.stream().collect(Collectors.toMap(Entity::getName, Entity::getId));
            name2IdMap = new ConcurrentHashMap<>(temp);
        }

        return name2IdMap.get(name);
    }

但是,当我尝试插入5000行时,我注意到缓存方式太慢了,我认为它应该快得多。有人可以对此发表评论吗?谢谢

更新:我记录了时间并进行了检查。该地图确实生效。更具体地说,第一次(加载到地图)需要更多时间。但是之后,它需要0毫秒才能找到ID。当我们有更多数据时,这确实提高了性能。但是,问题出在我从缓存中获得了这个经过验证的值之后,当我尝试稍后再从数据库中获取另一个对象(相同的代码)时,它花费的时间要长得多(从之前的12毫秒到现在的7秒钟)。变慢的代码是

public List<M> findByExample(M instance) {
            Criteria crit = getSession().createCriteria(getClass());
            Example example = Example.create(instance);
            crit.add(example);
            List<M> list = crit.list();
            return list;
}

通过日志记录,唯一的步骤是太多的时间是list(),我不知道为什么。导致以前从map或db获取值的方式似乎与此代码无关。我正在使用mysql。现在,我在考虑是否有一些事情,例如您不经常获取数据库(毫秒级别)时,他们会将其置于“睡眠”模式。

1 个答案:

答案 0 :(得分:0)

一些潜在原因,

  1. 您是否在多个线程上运行这段代码?如果没有, 当您将 ConcurrentHashMap 的性能与 单线程,但是添加更多线程来完成工作肯定会加快过程。
  2. 当处理具有成千上万条记录的数据时,
  3. ConcurrentHashMap 效率更高,而大小为5000的数据将不得不在内部做更多的工作来处理这种较小的数据集。 / li>

https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html