代码之家  ›  专栏  ›  技术社区  ›  Andreas Dolk

继承EJB3应用程序的性能优化策略

  •  1
  • Andreas Dolk  · 技术社区  · 14 年前

    我被要求看一看遗留的EJB3应用程序,它有严重的性能问题。原来的作者已经不可用了,所以我所得到的只是源代码和一些关于不可接受的性能的用户评论。我个人的EJB3技能是相当基本的,我可以阅读和理解注释代码,但这一切直到知道。

    服务器有一个数据库、几个ejb3bean(JPA)和几个无状态bean,只允许远程客户端在4..5域对象上使用CRUD。客户机本身就是一个java应用程序。只有少数并行连接到服务器。从用户的评论中我了解到

    • 客户机/服务器应用程序在局域网中表现良好
    • 由于读取和更新操作花费的时间太长(最多几分钟),因此该应用程序在WAN(1MBit或更多)上几乎不可用

    FetchType.EAGER . 这能解释读取操作的性能问题吗?是否建议开始调整获取策略?

    但这并不能解释更新操作的性能问题,是吗?更新由 EntityManager ,客户机只是将域对象传递给managerbean,而持久化只需要 manager.persist(obj) . 可能发送到服务器的域对象太大了(可能是急切策略的副作用)。

    所以我的实际理论是,太多的字节是通过相当慢的网络发送的,我应该考虑减小结果集的大小。

    根据您的经验,导致CRUD操作性能问题的典型和最常见的编码错误是什么?我应该从哪里开始调查/优化?

    4 回复  |  直到 14 年前
        1
  •  4
  •   Pascal Thivent    14 年前

    在所有的EJB上,所有的关系都是用抓取策略定义的FetchType.EAGER文件. 这能解释读操作的性能问题吗?

    根据类之间的关系,您可能会获取更多(整个数据库?)而不是检索实体时实际需要的?

    开始调整抓取策略是否明智?

    我不能说让所有的关系都变得急切是一种非常标准的方法。以我的经验,你通常让他们懒惰和使用

    但这并不能解释更新操作的性能问题,是吗?

    有可能。我的意思是,如果应用程序在读取时检索一个大的胖对象图,然后将同一个胖对象图发送回只更新根实体,那么可能会有性能损失。但代码使用 em.persist(Object) 实体。

    根据您的经验,导致CRUD操作性能问题的典型和最常见的编码错误是什么?我应该从哪里开始调查/优化?

    1. N+1请求问题(错误的获取策略)
    2. 不恰当的继承策略
    3. 不必要的数据库命中(即缺少缓存)

        2
  •  1
  •   baklarz2048    14 年前

    从DBA位置。

    根据您的经验,导致CRUD操作性能问题的典型和最常见的编码错误是什么?我应该从哪里开始调查/优化?

    1. 关掉 缓存
    2. 现在你明白我的意思了。
    3. 改变FetchType.EAGER文件至FetchType.LAZY文件
    4. 使用ehcache http://ehcache.org/
    5. 启用实体缓存
    6. 启用查询缓存

    http://www.google.com/search?q=hibernate+sucks

        3
  •  1
  •   Ralph    13 年前

    在我的案例中,类似的性能问题并不取决于fetch策略。或者说,在现有的fetch策略中改变业务逻辑是不可能的。在我的例子中,解决方法就是简单地添加索引。 例如,如果您有一个Customer和一个Address对象具有oneToOne关系,那么在第一次查看时一切都会很好。客户和地址有外键。但如果你这样做

    Select c from Customer as c where c.address.zip='8888'

    数据库中的SQL语句如下所示:

     ALTER TABLE `mydatabase`.`ADDRESS` ADD INDEX `zip_index`(`IZIP`);
    
        4
  •  0
  •   Community CDub    7 年前

    先看看发生了什么。如果你还没做那件事,我们都只是瞎猜。

    我不是这种系统的专家,但是 this method 适用于任何语言或操作系统。

    当你发现是什么让你花了太长时间,为什么不在这里总结一下呢? 我特别想知道是不是有人猜到了。