简体   繁体   English

休眠真的很慢。 如何让它更快?

[英]Hibernate really slow. How to make it faster?

In my app.在我的应用程序中。 I have Case and for each Case there can be 0 to 2 Claim .我有Case并且对于每个Case可以有 0 到 2 Claim If a Case has 0 claims it runs pretty fast, 1 claims and it slows down, and 2 is awfully slow.如果一个Case有 0 个索赔,它运行得非常快,1 个索赔它会变慢,而 2 个索赔非常慢。 Any idea how to make this faster?知道如何加快速度吗? I didn't know if my case and claim were going back and forth causing an infinite recurison, so I added a JsonManagedReference and JsonBackReference, but that doesn't seem to help much with speeds.我不知道我的案例和声明是否来回导致无限递归,所以我添加了 JsonManagedReference 和 JsonBackReference,但这似乎对速度没有太大帮助。 Any ideas?有任何想法吗? Here is my Case.java:这是我的 Case.java:

@Entity
public class Case {
    @OneToMany(mappedBy="_case", fetch = FetchType.EAGER)
    @Fetch(FetchMode.JOIN)
    @JsonManagedReference(value = "case-claim")
    public Set<Claim> claims;
}

In Claim.java:在 Claim.java 中:

@Entity
public class Claim implements Cloneable {

    @ManyToOne(optional = true)
    @JoinColumn(name = "CASE_ID")
    @JsonBackReference(value = "case-claim")
    private Case _case;
}

output of 0 claims: https://gist.github.com/elmatt/2cafbe7ecb1fa0b7f6a8 0 个声明的输出: https : //gist.github.com/elmatt/2cafbe7ecb1fa0b7f6a8

output of 2 claims: https://gist.github.com/elmatt/b000bc28909453effc95 2 项声明的输出: https : //gist.github.com/elmatt/b000bc28909453effc95

Your problem has nothing to do with the relationship between Case and Claim.您的问题与 Case 和 Claim 之间的关系无关。

FYI: 300ms is not "pretty fast."仅供参考:300 毫秒并不是“相当快”。 Your problem is that you expect hibernate to magically and quickly deliver a complex object hierarchy to you, with no particular effort on your part.您的问题是,您希望 hibernate 能够神奇地、快速地向您提供复杂的对象层次结构,而无需您付出特别的努力。 I view ORM as "The Big Lie" - it is super easy to use and works great on toy problems, but tends to fail miserably when you try to scale to interesting applications (like yours).我认为 ORM 是“大谎言”——它非常易于使用并且在玩具问题上效果很好,但是当您尝试扩展到有趣的应用程序(如您的应用程序)时往往会失败。

Don't abandon hibernate, but realize that you are going to need to work harder than you thought you would in order to make it work for you.不要放弃休眠,但要意识到你需要比你想象的更努力才能让它为你工作。

I happen to work in a similar data domain (post-adjudication healthcare claim analysis and processing).我碰巧在类似的数据领域工作(裁定后医疗保健索赔分析和处理)。 You should be able to select this kind of data in well under 10ms per claim (with all associated dimensions) using MySQL on modest hardware from a table with >1 billion claims and the DB hosted on a separate server from the app.您应该能够在每个声明(包括所有相关维度)的 10 毫秒内从具有超过 10 亿个声明的表和托管在与应用程序不同的服务器上的数据库中的中等硬件上使用 MySQL 来选择此类数据。

How do you get from where you are to where you should be?你如何从你所在的地方到你应该去的地方? 1. Minimize the number of round-trips to the database by minimizing the number of separate queries that are executed. 1. 通过最小化执行的单独查询的数量来最小化到数据库的往返次数。 2. Hand-craft your important queries to grab just the rows and joins that you actually need. 2. 手工制作您的重要查询以仅获取您实际需要的行和连接。 3. Use explain plan on every query to make sure that it hits the tables in the right order and every step is appropriately supported by an index. 3. 对每个查询使用explain plan以确保它以正确的顺序访问表,并且每个步骤都得到索引的适当支持。 4. Consider partitioning your big tables and include the partition criteria in your queries to enable partition-pruning to focus the query on the proper data. 4. 考虑对大表进行分区,并在查询中包含分区标准,以启用分区修剪以将查询集中在正确的数据上。 5. Be very hesitant to let hibernate manage your relationships between your entities. 5. 非常犹豫是否让 hibernate 管理您的实体之间的关系。 I generally do not let hibernate deal with any relationships.我一般不让hibernate处理任何关系。

A few years ago, I worked on a product that is an iPhone app where the user walks through workflows (eg, a nurse taking a patient's vitals) and each screen made a round-trip to the app server to execute the workflow step and get the data for the next screen.几年前,我开发了一个 iPhone 应用程序产品,用户可以在其中浏览工作流程(例如,护士测量患者的生命体征),并且每个屏幕都往返于应用程序服务器以执行工作流程步骤并获得下一个屏幕的数据。 Think about how little data you can work with on an iPhone screen.想想你可以在 iPhone 屏幕上处理多少数据。 Yet the DB portion of the round-trip generally took 2-5 seconds to execute.然而,往返的 DB 部分通常需要 2-5 秒来执行。 Everyone there took it for granted, because "That is how long it has always taken."那里的每个人都认为这是理所当然的,因为“这总是需要多长时间。” I dug into the code and found that each step was pulling in a significant portion of the database (and then was not used by the business logic).我深入研究了代码,发现每一步都拉入了数据库的很大一部分(然后没有被业务逻辑使用)。

The only time they tweaked the default hibernate behavior was when they got an exception due to too many joins (yes, MySQL has a limit of something like 67 tables in one query).他们唯一一次调整默认的休眠行为是由于连接过多而导致异常(是的,MySQL 在一个查询中限制为 67 个表)。

The approach of creating your Java data model and simply ORM'ing it into the database generally works just fine on configuration data and the like, but tends to perform terribly for complex data models involving your transactional data.创建 Java 数据模型并简单地将其 ORM 到数据库中的方法通常适用于配置数据等,但对于涉及事务数据的复杂数据模型往往表现不佳。 This is what is biting you now.这就是现在正在咬你的东西。

Your problem is totally fixable, and can be attacked incrementally - you don't have to tear apart the whole application to start making things better.您的问题是完全可以解决的,并且可以逐步解决 - 您不必拆开整个应用程序来开始改进。

Can you enable hibernate logging and provide the output.您能否启用休眠日志记录并提供输出。 It should indicate the SQL queries being executed against your DB.它应该指示正在对您的数据库执行的 SQL 查询。 Information about which DB you are using would also be useful.有关您正在使用的数据库的信息也很有用。 When you have those I would recommend profiling the queries to ensure your DB is setup appropriately.当您拥有这些时,我建议您分析查询以确保正确设置您的数据库。 It sounds like an non indexed query.这听起来像是一个非索引查询。

Size of the datasets would be helpful in targeting possible issues as well - number of rows and so on.数据集的大小也有助于定位可能的问题 - 行数等。

I would also recommend timing the actual hibernate call (could be as crude as log statement immediately before / after) vs overall processing to identify whether it really is hibernate or some other processing.我还建议对实际的休眠调用(可能像之前/之后的日志语句一样粗糙)与整体处理进行计时,以确定它是真正处于休眠状态还是其他一些处理。 Without further information & context that is not clear here.没有进一步的信息和上下文,这里不清楚。


Now you've posted your queries we can see what is happening.现在您已经发布了您的查询,我们可以看到正在发生的事情。 It looks like the structure of your entities is more complex than the code snippet originally posted.看起来您的实体结构比最初发布的代码片段更复杂。 There are references to Person, Activities, HealthPlan and others in there.那里有对人员、活动、健康计划等的引用。

As others have commented your query is triggering a very large select of a lot of data due to the nature of your model.正如其他人评论的那样,由于模型的性质,您的查询触发了大量数据的大量选择。

I recommend creating Named Queries for claims, and then load those using the ID of Case.我建议为声明创建命名查询,然后使用案例 ID 加载这些查询。

You should also review your hibernate model and switch to FetchType.LAZY, other hibernate will create large queries such as the one you have posted.您还应该检查您的休眠模型并切换到 FetchType.LAZY,其他休眠将创建大型查询,例如您发布的查询。 The catch here is that if you try to access a related entity outside of the transaction you will get a lazyinitializationexception.这里的问题是,如果您尝试访问事务之外的相关实体,您将获得lazyinitializationexception。 You will need to consider each use case and ensure you load the data you need.您需要考虑每个用例并确保加载所需的数据。 Two common mistakes with Hibernate is to use FetchType.EAGER everywhere or to initiate the transaction to early to avoid this. Hibernate 的两个常见错误是到处使用 FetchType.EAGER 或尽早启动事务以避免这种情况。 There is not one correct design approach, but I normally do the following没有一种正确的设计方法,但我通常会执行以下操作

JSP -> Controller -> [TX BOUNDARY] Service -> DAO JSP -> 控制器 -> [TX BOUNDARY] 服务 -> DAO

You service method(s) should encapsulate the business logic you need to load the data you require, before passing it back to the controller.在将数据传递回控制器之前,您的服务方法应封装加载所需数据所需的业务逻辑。

Again, per the other answer, I think you're expecting too much of Hibernate.同样,根据另一个答案,我认为您对 Hibernate 期望过高。 It is a powerful tool but you need to understand how it works to get the best from it.它是一个强大的工具,但您需要了解它的工作原理才能从中获得最佳效果。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 FileOutputStream很慢。 如何更快地做到这一点? - FileOutputStream is slow. How can this be done faster? 如何使休眠查询更快 - How to make hibernate query faster 我正在使用Euler 12,我的代码似乎正常工作,但是太慢了,非常非常慢。 如何修改使其运行更快? - I'm working on Euler 12 , the code i have seems to workes properly but too slow , very very slow. How can i modify it to run faster? java System.nanoTime 真的很慢。 是否可以实现高性能 java 分析器? - java System.nanoTime is really slow. Is it possible to implement a high performance java profiler? 如何使用多线程使缓慢的“for 循环”更快? - How do I make a slow “for loop” faster with multithreading? Errai(GWT)的编译速度太慢-制作速度更快 - Errai (GWT) compilation is too slow — how to make is faster 如何在使用大量记录时使用Hibernate更快地进行更新 - How to make update faster with Hibernate while using huge number of records weka.attributeSelection.InfoGainAttributeEval太慢。 关于如何加快速度的任何想法? - weka.attributeSelection.InfoGainAttributeEval is too slow. Any ideas on how to speed it up? Neo4J Java Bolt CREATE节点很慢。 怎么改进呢? - Neo4J Java Bolt CREATE Node is slow. How to improve it? 为什么 Java HTTP 请求这么慢(与 Python 相比),我怎样才能让它们更快? - Why are Java HTTP requests so slow (in comparison to Python), and how can I make them faster?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM