使用投影可以提高Hibernate Search索引的构建性能吗?

马格努斯

我有一个包含约40列和7个集合的实体。集合不是延迟加载的。使用Hibernate Search MassIndexer为500 000个实体建立索引大约需要2-3个小时。我使用下面的代码:

fullTextSession.createIndexer()
        .batchSizeToLoadObjects(1000)
        .threadsToLoadObjects(8).start();

我什至尝试使用延迟加载来了解它们之间的区别,然后大约需要1个小时,这没有我希望的那样快。

为了测试性能,如果一个实体仅包含我要索引的列,包括ID列的3列,我将创建一个仅包含这三列的实体。现在索引编制非常迅速,只用了3分钟。

使用不同实体的方法不是我想要的,因为每次更新原始实体时,就需要手动更新索引(据我所知,它是如何工作的)。然后,我想到了使用flushToIndexes()方法和投影来代替MassIndexer。

我根据https://docs.jboss.org/hibernate/search/4.4/reference/zh-CN/html_single/#search-batchindex-flushtoindexes编写了以下代码,并添加了投影部分。

Session session = sessionFactory.openSession();
try {
    int batchSize = 1000;
    FullTextSession fullTextSession = Search.getFullTextSession(session);
    fullTextSession.setFlushMode(FlushMode.MANUAL);
    fullTextSession.setCacheMode(CacheMode.IGNORE);
    Transaction transaction = fullTextSession.beginTransaction();
    //Scrollable results will avoid loading too many objects in memory
    ScrollableResults results = fullTextSession.createCriteria( Report.class )
        .setProjection(Projections.projectionList()
                .add(Projections.property("reportId"), "reportId")
                .add(Projections.property("header"), "header")
                .add(Projections.property("description"), "description")
                )
        .setResultTransformer(Transformers.aliasToBean(Report.class))
        .setFetchSize(batchSize)
        .scroll( ScrollMode.FORWARD_ONLY );
    int index = 0;
    while( results.next() ) {
        index++;
        fullTextSession.index( results.get(0) ); //index each element
        if (index % batchSize == 0) {
            fullTextSession.flushToIndexes(); //apply changes to indexes
            fullTextSession.clear(); //free memory since the queue is processed
        }
    }
    transaction.commit();
} catch (Exception e) {
    log.error(e);
} finally {
    session.close();
}

在运行代码时,当我fullTextSession.index(results.get(0));尝试索引第一个元素时,我在代码中出现了异常(at ):

org.hibernate.TransientObjectException:实例与此会话没有关联

我不明白为什么会收到这个例外。我已经读到,如果使用不同的Hibernate会话,可能会发生这种情况,但是在这种情况下,我将在一个Hibernate会话中完成所有工作。

有没有其他人试图将投影与Hibernate Search索引一起使用?应该可以使用吗?对此主题的任何信息表示赞赏。

一些版本信息:我正在使用Hibernate 4.2.17.Final和Hibernate Search 4.4.6.Final。由于依赖关系,我无法使用最新版本。

桑内

(目前)不选择使用投影,因为投影结果与对象无关:它是瞬态的。FullTextSession#指数()方法需要被管理对象,所以你得到的TransientObjectException

回到设计MassIndexer时,我曾考虑使用投影,但似乎并没有给我带来明显的好处。有趣的是,您报告这对您的情况很有用。您确定所有关系都是惰性的,并且确定索引过程将不需要那些懒惰的关系吗?

如果您可以通过加载较少的数据列来确认可以看到如此显着的性能优势,那么我们可以考虑对其进行修补。理想情况下,我们可以使此优化对用户透明,而无需添加更多配置选项。

以我的经验,主要的速度下降是由于数据库需要多次往返来加载所有关系。通常,通过确保所有关系都是惰性的并为索引期间需要加载的关系启用二级缓存,可以大大提高性能。根据模型的不同,缓存可能比投影更有效。

但是我意识到我正在对实体的建模方式做一些假设,因此您的报告非常有趣。在我们的问题跟踪器上打开新的“改进” JIRA

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在MYSQL表上拖放并重新创建索引,会提高性能吗?

我可以在JTA中使用Hibernate吗?

我什么时候应该在常规线程上使用asyncio,为什么?它可以提高性能吗?

可以提高syslog性能吗?

可以提高syslog性能吗?

如何提高Java中的Hibernate性能?

带有ListenAndServe的Goroutine可以提高性能吗?

使用C ++ 11的“自动”可以提高性能吗?

将Elasticsearch索引设为只读会提高性能吗?

您可以在Entity Framework导航属性上使用投影吗?

使用INDEX代替唯一索引是否可以提高写入性能?

在Flutter(Dart 2)中还是可以使用const关键字来提高性能吗?

使用SQL Server索引提高性能

PostgreSQL:由未使用的索引引起的查询性能差吗?

在更多线程中使用Python gRPC客户端存根时,可以提高性能吗?

如何使用Numpy构建的集合字典提高性能?

可以缓存JSON以提高性能/加载时间吗?

Windows 7 Updates确实可以提高系统性能吗?

避免使用单个变量会提高JavaScript性能吗?

CUDA,使用共享内存可以提高我的性能吗?

DBMS使用索引来提高性能(带有示例)

使用可为空的结构是否可以提高性能?

我可以提高我的GCE小型实例的性能吗?

我可以使用索引提高此请求的效率吗?

Hibernate Search 5.5.2-具有许多关联的对象的索引更新性能较差

Matlab:如果“A”是索引变量,则可以使用逻辑索引而不是 FIND 来提高性能

提高 Mysql 查询性能(索引类型使用说明)

使用缓存会提高函数式编程的性能吗?

在我的情况下,索引会提高读取性能吗?