当select比a快时?

时间:2014-10-13 18:54:21

标签: java database performance hibernate jpa

想象一下这种情况,我有一个实体的Id,我有一个喜欢的列表,其中包含同一类的一些实体。要查找实体,何时更快在链表中执行for或在数据库中执行选择?

我的意思是,例如,当我在链表中​​有大约5个实体时,我想有一个for更快,而当我拥有数百万个实体时,select会更快。

但是当选择开始比for更快时?

2 个答案:

答案 0 :(得分:5)

内存数据结构总是比打开套接字,运行查询和发回响应更快。

一个好的查询可能在10-100ms内运行,而Java操作可能需要100ns。

使用LinkedList可能无法获得最佳性能。类似于使用数据库索引,您可以改为使用HashMap,并通过其ID来映射实体:

Map<Long, Entity> idEntityMap = new HashMap<>;
idEntityMap.put(entity.getId(), entity);

因此,当您搜索实体时,只需运行:

Entity entity = idEntityMap.get(entityId);

该呼叫将首先识别实体所在的Map存储桶,并仅对该存储桶中包含的实体进行对象比较。

总而言之,内存中的操作速度非常快,但您需要使用适合您用例的数据结构。

答案 1 :(得分:1)

我机器上的1e5元素后速度更快*。 从具有一个记录槽jpa的表中进行选择的基线是1ms。

  

置信区间(99.9%):[0,747,1,087]

从1e5记录中选择将同时(1ms)下限增加0.1ms。

在1e5元素列表中的顺序搜索,其中所需元素最后放置2ms。

  

置信区间(99.9%):[2073669,347,2514442,020]

对所需元素的随机发布进行除法,将其除以2。

从1e5元素的地图中获取实体的费用将少于30ns

以下是我的同行评审基准:

EntityManagerFactory emf;
List<Individual> list;
Map<Integer, Individual> map;

@Setup
public void setUp() {
    emf = Persistence.createEntityManagerFactory("postgres");
    list = new ArrayList<Individual>();
    map = new HashMap<Integer, Individual>();

    for (int i = (int)1e5; i > 0; i--) {
        Individual individual = new Individual(i);
        list.add(individual);
        map.put(i, individual);
    }
}

@TearDown
public void tearDown() {
    emf.close();
}

@Benchmark
@Fork(1)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public Individual measureJpa() {
    EntityManager em = emf.createEntityManager();

    Query query = em.createQuery("select i from com.company.Individual i where i.id = 1");

    em.getTransaction().begin();

    Individual individual = (Individual) query.getSingleResult();

    em.getTransaction().commit();

    em.close();

    return individual;
}

@Benchmark
@Fork(1)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public Individual measureList() {
    for (Individual i : list) {
        if (i.id == 1) {
            return i;
        }
    }
    throw new RuntimeException();
}

@Benchmark
@Fork(1)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public Individual measureMap() {
    return map.get(1);
}
  • 双核1.5GHz CPU,7200rmp HDD,600MHz RAM,Windows 7 x64,JDK 1.8.0_05,EclipseLink 2.5.1,PostgesSql 9.3