什么会减缓Hibernate/Oracle的速度?

3

我有一个Java应用程序在Windows服务器上运行。该应用程序通过Hibernate查询Oracle 10数据库。我有一个查询返回215个实体,每个实体有6个字符串字段。获取它们需要约20秒钟(从Hibernate统计信息中获得的数据)。

我获取了由Hibernate生成的SQL,并通过SQLPlus运行它,运行时间介于300-500毫秒之间。

我使用ojdbc驱动程序(与我的应用程序使用相同的驱动程序)启动了H2控制台,并连接到我的数据库(从与我的应用程序运行在同一台计算机以避免网络问题的计算机上),多次运行了我从Hibernate获取的SQL,我得到与SQLPlus相同的300-500毫秒运行时间,因此我认为我的问题来自Hibernate,但我不知道还要查找什么。

数据库位于另一台服务器上,但我对该服务器的ping延迟小于1毫秒,因此我认为网络没有参与其中。

我的配置:

javax.persistence.jdbc.driver=oracle.jdbc.driver.OracleDriver
javax.persistence.jdbc.url=jdbc:oracle:thin:@xxxxx
javax.persistence.jdbc.user=xxxxx
javax.persistence.jdbc.password=xxxxx
hibernate.ejb.naming_strategy=org.nuiton.jpa.hibernate.OracleCompliantImprovedNamingStrategy
hibernate.dialect=xxxx.MyDialect

hibernate.hbm2ddl.auto=update
hibernate.show_sql=false
hibernate.use_sql_comments=false
hibernate.format_sql=true
hibernate.ejb.naming_strategy=org.hibernate.cfg.ImprovedNamingStrategy

hibernate.c3p0.min_size=3
hibernate.c3p0.max_size=5
hibernate.c3p0.timeout=1800
hibernate.c3p0.max_statements=50

hibernate.generate_statistics = false

Naming Strategy: 命名策略,具体可参考https://gitlab.nuiton.org/retired/nuiton-jpa/blob/develop/nuiton-jpa-hibernate/src/main/java/org/nuiton/jpa/hibernate/OracleCompliantImprovedNamingStrategy.java
Dialect: 方言。
public class MyDialect extends Oracle10gDialect {

    public MyDialect() {
        super();
        registerColumnType(Types.DOUBLE, "number");
    }

}

我的实体看起来像这样(包括getter和setter):

public abstract class AbstractJpaRequestedArticle extends AbstractJpaEntity implements Serializable {

    private static final long serialVersionUID = 7293079560062973232L;

    public static final String PROPERTY_ID = "id";

    public static final String PROPERTY_QUANTITY = "quantity";

    public static final String PROPERTY_PRIORITY = "priority";

    public static final String PROPERTY_ARTICLE = "article";

    public static final String PROPERTY_REQUESTED_LIST = "requestedList";

    public static final String PROPERTY_DESTINATION_LOCATION = "destinationLocation";

    @Id
    protected String id;

    protected double quantity;

    protected String priority;

    @ManyToOne
    protected Article article;

    @OneToOne
    protected RequestedList requestedList;

    @ManyToOne
    protected Location destinationLocation;

    @PrePersist
    public void prePersist() {
        if (this.id == null) {
            this.id = new JpaEntityIdFactoryResolver().newId(this);
        }
    }

    @Override
    public String getId() {
        return id;
    }

AbstractJpaEntity仅定义了equals、hashcode和默认的toString方法。


你能否尝试使用Log4j为Hibernate设置日志配置呢?这将更好地展现幕后发生的情况。此外,第一个查询可能比后续查询花费更多时间。 - Chaitanya
修改了包含 Hibernate 配置的问题。 - Jean Couteau
@ChaitanyaWaikar 我应该在 Hibernate 上设置哪个日志级别? - Jean Couteau
请参考以下链接:https://dev59.com/pmw15IYBdhLWcg3wcbWy#6609980 - Chaitanya
1
尝试将hibernate.jdbc.fetch_size设置为100-500,看看是否会有所改善。据我所知,如果查询在Oracle中运行良好,唯一的问题可能是获取结果。请参考http://makejavafaster.blogspot.com/2015/06/jdbc-fetch-size-performance.html。 - Amit Naik
显示剩余12条评论
1个回答

0

回到我的问题,提供我长期寻找答案的解决方法。

正如@AmitNaik所指出的那样,我的问题出现在未设置抓取大小上,因此使用了默认值(10)。我尝试在Hibernate参数中放入不同的值,但没有成功。似乎在我的Hibernate版本中,该参数在我的entityManagerFactory中不起作用(为什么?)。因此,我必须在我的特定查询中设置抓取大小,并解决了我的问题(现在在我的测试用例中约为600毫秒)。正如@john16384所说,我现在必须调查我的SQL查询,但那是另一回事。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接