当前位置: 首页 > 知识库问答 >
问题:

执行HQL查询需要很长时间

汤枫涟
2023-03-14

我知道要冬眠。我有一个sql语句

SELECT VERSION_ID,D_BEGIN,D_END, 
 (SELECT NAME FROM zvit where ZVIT_ID=version.ZVIT_ID) as name  
 FROM version  
 where  VERSION_ID in  
 (SELECT term.VERSION_ID FROM term  
 where term.PERIOD_MONTH= :periodMonth and term.PERIOD_TYPE= :periodType and term.PERIOD_YEAR= :periodYear )  
 order by 1 ;

我尝试用createCriteria和HQL实现它。

    DetachedCriteria subQuery  = DetachedCriteria.forClass(TermData.class)
            .add(Restrictions.eq("periodmonth",  periodMonth))
            .add(Restrictions.eq("periodtype",  periodType))
            .add(Restrictions.eq("periodyear", periodYear))
            .setProjection(Projections.projectionList() 
                    .add(Projections.property("versionId.versionId"))
                    );          
    Criteria versionCriteria = session.createCriteria(VersionData.class)
            .addOrder(Order.asc("versionId"))
            .add(Subqueries.propertyIn("versionId", subQuery))
            .createAlias("zvitId", "zvitId", org.hibernate.sql.JoinType.INNER_JOIN)
            .setProjection(Projections.projectionList() 
                    .add(Projections.property("versionId"))
                    .add(Projections.property("dbegin"))
                    .add(Projections.property("dend"))
                    .add(Projections.property("zvitId.name"), "name")

                    );  

HQL:

            Query query = session.createQuery(""
                    + "from VersionData as version "
//                  + "inner join version.zvitId as zvit "
                    + "where version.versionId in "
                    + "(select term.versionId from TermData as term "
                    + "where term.periodmonth= :periodmonth and term.periodtype= :periodtype and term.periodyear= :periodyear)");

问题是,此HQL的执行时间延长了10倍。并执行许多不必要的查询。我尝试使用注释字符串进行转换,它有了一些改进,但仍然比createCriteria查询长5倍,此外,我无法进行此转换

<代码>列表

版本数据防御

@Entity
@Table(name = "version")
public class VersionData implements Serializable
{

    /**
     * 
     */
    private static final long serialVersionUID = 7355281418627668744L;

    @Id 
    @Column(name="VERSION_ID")  
    private String versionId;   

    /**
     * user dbegin
     */
    @Column(name = "D_BEGIN")
    @Type(type = "date")
    private Date dbegin;

    /** user dend */
    @Column(name = "D_END")
    @Type(type = "date")
    private Date dend;  


    /**
     * user zvitId
     */
    @ManyToOne
    @JoinColumn(name="ZVIT_ID") 
    private ZvitData zvitId;

    @OneToMany(targetEntity=TermData.class, mappedBy = "versionId", cascade=javax.persistence.CascadeType.ALL, fetch=FetchType.LAZY)
    private List<TermData> terms;
//getters, setters, hashcode, equals
}

共有1个答案

汝志
2023-03-14

好的,使用您发布的条件查询,您只获取所需的字段,而使用HQL查询,您获取整个Hibernate托管实体(VersionData)。根据该实体的配置方式,您可能会看到其他查询被激发以填充该实体的字段。

您可以使用HQL对标准做同样的事情,在我看来,它比使用标准更容易理解和维护。只需为您要获取的字段定义一个java类MyClass,并使用适当的构造函数,然后调用一个HQL查询,如下所示:

"select new path.to.myclass.MyClass ( "
                + " alias1.field1, "
                + " alias2.field2, "
                + " ... "

其中别名是您在HQL查询中为实体提供的名称(例如,version是您编写的查询中VersionData的别名)。没有投影,没有额外的抽象,只是一个类似SQL的查询。

您可以直接获取字段,然后处理返回的结果,而不是定义一个新类来保存从HQL查询返回的字段(我发现这更方便),如下面的链接所示:

如何在JPQL或HQL中仅检索实体的某些字段?JPQL或HQL中ResultSet的等价物是什么?

 类似资料:
  • 我有以下PHP代码在Laravel正在执行一个MySql查询: 执行此查询需要很长时间。 我对所排序的列以及其他查询的许多列都有索引。 我该怎么办? 更新: 执行的查询: 结果:

  • 问题内容: 我有一个以datetime为参数的查询,我们观察到的是,如果通过变量提供datetime参数,则执行查询的时间比直接对参数进行硬编码要多2 -3倍,是否有任何原因或解决方案?对此 以下查询大约需要5分钟才能返回结果 虽然作为 它会在10到20秒内返回 我并不总是希望在列上使用索引进行搜索。 按照kevchadders的建议,我看到执行计划有很大的不同。使用日期变量的查询正在执行聚集索引

  • 没有一个参数帮助我们在较短的时间内解决查询。

  • 我的Mongo Collection有大约2000个文档。当使用MongoTemplate find()方法和空查询(即我需要集合中的所有文档)和实体类、集合名称时,以列表的形式返回数据需要一分钟以上。有人能帮我让查询返回更快吗??下面是我正在使用的查询。

  • 使用执行hql查询时出现错误 我的疑问是 堆栈跟踪是

  • 我有一个查询,我用了很长时间才找到。我在一个有500k行的表的单个分区上运行它。 查询如下所示: 我将其设置为,因此查询返回0行。 此查询大约需要30秒(如果我使用,则需要一分钟)。 当我运行完全相同的查询但使用时,需要2秒。 是什么原因导致查询在使用选择列时花费很长时间,而在使用选择计数(列)时不花费时间? 这是解释的问题 *项目[col0#607] -*过滤器(isnotnull(col1#6