相关疑难解决方法(0)

使用Hibernate的ScrollableResults慢慢读取9000万条记录

我只需要使用Hibernate读取MySQL数据库中表中的每一行,并根据它编写一个文件.但是有9000万行,它们非常大.所以看起来以下是合适的:

ScrollableResults results = session.createQuery("SELECT person FROM Person person")
            .setReadOnly(true).setCacheable(false).scroll(ScrollMode.FORWARD_ONLY);
while (results.next())
    storeInFile(results.get()[0]);
Run Code Online (Sandbox Code Playgroud)

问题是上面将尝试将所有9000万行加载到RAM中,然后再转到while循环...这将使OutOfMemoryError消除我的内存:Java堆空间异常:(.

所以我猜ScrollableResults不是我想要的?处理这个问题的正确方法是什么?我不介意这个while循环需要几天(好吧我不喜欢它).

我想处理这个问题的另一种方法是使用setFirstResult和setMaxResults迭代结果,只使用常规的Hibernate结果而不是ScrollableResults.这感觉就像它效率低下一样,当我在8900万行中调用setFirstResult时,它将开始花费一段可笑的时间......

更新:setFirstResult/setMaxResults不起作用,事实证明需要花费相当长的时间才能达到我所担心的偏移量.这里一定有解决方案!这不是一个很标准的程序吗?我愿意放弃Hibernate并使用JDBC或其他任何东西.

更新2:我提出的解决方案哪个工作正常,不是很好,基本上是以下形式:

select * from person where id > <offset> and <other_conditions> limit 1
Run Code Online (Sandbox Code Playgroud)

由于我有其他条件,即使是索引中的所有条件,它仍然没有我想要的那么快......所以仍然可以提供其他建议..

java mysql hibernate large-data-volumes scrollableresults

52
推荐指数
4
解决办法
8万
查看次数

使用flushMode = AUTO时,Hibernate查询要慢得多,直到调用clear()为止

我有一个使用Hibernate(通过JPA)的长期运行(但相当简单)的应用程序.它经历了相当剧烈的放缓.我已经能够缩小到需要偶尔entityManager.clear()打电话.当Hibernate的实体管理器跟踪100,000个实体时,它比仅跟踪几个实体的速度慢约100倍(见下面的结果). 我的问题是:为什么 Hiberate在追踪很多实体的时候会这么慢?还有其他方法吗?


!更新:我已经能够将其缩小到Hibernate的自动刷新代码.!

具体到org.hibernate.event.internal.AbstractFlushingEventListener's flushEntities()方法(至少在Hibernate 4.1.1.Final中).在其中有一个循环遍历持久化上下文中的所有实体,执行一些广泛的检查来清除它们中的每一个(即使在我的示例中已经刷新了所有实体!).

因此,部分回答我的问题的第二部分,可以通过FlushModeType.COMMIT在查询上设置刷新模式来解决性能问题(请参阅下面的更新结果).例如

Place place = em.createQuery("from Place where name = :name", Place.class)
    .setParameter("name", name)
    .setFlushMode(FlushModeType.COMMIT)  // <-- yay!
    .getSingleResult();
Run Code Online (Sandbox Code Playgroud)

...但这似乎是一个相当丑陋的解决方案 - 传递责任,知道是否将事物刷新到查询方法而不是将其保留在更新方法中.它也意味着我要么必须在所有查询方法上将flush模式设置为COMMIT,要么更有可能在EntityManager上设置它.

这让我想知道:这是预期的行为吗?我是否在刷新或者如何定义实体时出错?或者这是Hibernate的限制(或可能是错误)?


我用来隔离问题的示例代码如下:

测试实体

@Entity @Table(name="place") @Immutable
public class Place {
    private Long _id;
    private String _name;

    @Id @GeneratedValue
    public Long getId() { return _id; }
    public void setId(Long id) { _id = id; }

    @Basic(optional=false) @Column(name="name", length=700,
        updatable=false, nullable=false, unique=true, …
Run Code Online (Sandbox Code Playgroud)

hibernate jpa

19
推荐指数
2
解决办法
9696
查看次数

如何使用JPA(或至少使用Hibernate)处理大型数据集?

我需要让我的网络应用程序使用非常庞大的数据集.目前我得到的是OutOfMemoryException或输出1-2分钟.

让我们把它简单,假设我们有在DB 2个表:WorkerWorkLog在第一个约1000列,并在第二个10个000 000行.后期表有几个字段,包括'workerId'和'hoursWorked'字段等.我们需要的是:

  1. 计算每个用户的总工作小时数;

  2. 每个用户的工作时间列表.

纯SQL中每个任务最直接的方法(IMO)是:

1)

select Worker.name, sum(hoursWorked) from Worker, WorkLog 
   where Worker.id = WorkLog.workerId 
   group by Worker.name;

//results of this query should be transformed to Multimap<Worker, Long>
Run Code Online (Sandbox Code Playgroud)

2)

select Worker.name, WorkLog.start, WorkLog.hoursWorked from Worker, WorkLog
   where Worker.id = WorkLog.workerId;

//results of this query should be transformed to Multimap<Worker, Period>
//if it was JDBC then it would be vitally 
//to set resultSet.setFetchSize (someSmallNumber), ~100
Run Code Online (Sandbox Code Playgroud)

所以,我有两个问题:

  1. 如何使用JPA(或至少使用Hibernate)实现我的每个方法;
  2. 你会如何处理这个问题(当然有JPA或Hibernate)?

java performance hibernate jpa java-ee

18
推荐指数
1
解决办法
4万
查看次数

什么时候应该指定setFetchSize()?

我看到很多JDBC/MySQL的"最佳实践"指南告诉我指定setFetchSize().

但是,我不知道何时指定,以及要指定的内容(语句,结果集).

Statement.setFetchSize() or PreparedStatement.setFetchSize() 
ResultSet.setFetchSize()
Run Code Online (Sandbox Code Playgroud)
  1. 在这两个中,我应该指定什么?
  2. javadocoracle文档中,这是我对"何时"感到困惑的地方

的Javadoc

默认值由创建结果集的Statement对象设置.可以随时更改提取大小.

Oracle Doc

生成结果集后对语句对象的提取大小所做的更改将不会影响该结果集.

如果我错了,请纠正我.这是否意味着setFetchSize在执行查询之前只是Affective?(因此,ResultSet上的setFetchSize是无用的?但是恰好"可以随时更改获取大小"?)

java mysql sql oracle jdbc

11
推荐指数
1
解决办法
1万
查看次数

快速获得hibernate结果的方法?

我目前在我的项目中设置了hibernate.它适用于大多数事情.但是今天我需要从表中返回几十万行查询.它是表中总行数的约2/3s.问题是查询需要大约7分钟.使用直接JDBC并执行我假设的相同查询,它需要<20秒.因此,我认为我做的事情完全错了.我将在下面列出一些代码.

DetachedCriteria criteria  =DetachedCriteria.forlass(MyObject.class);
criteria.add(Restrictions.eq("booleanFlag", false));
List<MyObject> list = getHibernateTemplate().findByCriteria(criteria);
Run Code Online (Sandbox Code Playgroud)

关于它为什么会变慢和/或我可以做些什么来改变它的想法?

java oracle hibernate

4
推荐指数
2
解决办法
2832
查看次数