【问题标题】:How to decrease query execution time using JPQL query如何使用 JPQL 查询减少查询执行时间
【发布时间】:2019-07-22 23:20:51
【问题描述】:

我正在尝试选择一些文档表列并将它们映射到新对象,而不是返回整个文档。我非常担心以下查询的执行时间,因为执行约 35,000 个条目需要约 4200 毫秒。减少执行时间的最佳解决方案是什么? 4 秒是 35,000 个条目的好时间吗?

    @Query("SELECT DISTINCT new it.homepackage.models.document.DocumentGetReviewCommand(" +
        "d.author.firstname, d.author.lastname, d.id, d.title, d.description, d.documentType.title, d.submissionDate)" +
        " FROM Document d" +
        " WHERE d.documentType IN :docTypes" +
        " AND d.documentState = it.homepackage.enums.DocumentState.SUBMITTED" +
        " AND :username <> d.author.username")
Page<DocumentGetReviewCommand> getDocumentsForReview(@Param(value = "username") String username,
                                                     Pageable pageable, 
                                                     @Param(value = "docTypes") List<DocumentType> docTypes);

【问题讨论】:

  • 获取真正的 SQL 查询,获取它的执行计划,看看可以改进它的地方。从您发布的内容中无法判断问题所在。
  • 这不会改变一切,但为什么在这个查询中需要DISTINCT?另外,:docTypes 列表有多大?
  • 是的,你是对的。我在重构代码后忘记删除它。 :typeList 从 5 到 20 不等

标签: hibernate spring-boot jpql


【解决方案1】:

您可以开始组织 JOIN。当您在 JPQL 上的实体(如 entity1.entity2.entity3.name)中使用复杂的“train wreck”时,Hibernate 会生成奇怪的(有时是无效的)SQL。

首先,查询可能是:

SELECT DISTINCT new it.homepackage.models.document.DocumentGetReviewCommand(" +
        "author.firstname, author.lastname, d.id, d.title, d.description, documentType.title, d.submissionDate)" +
        " FROM Document d" +
        " JOIN d.author author " +
        " JOIN d.documentType documentType " +
        " WHERE d.documentType IN :docTypes" +
        " AND d.documentState = it.homepackage.enums.DocumentState.SUBMITTED" +
        " AND :username <> author.username

如果查询仍然很慢,可能原因是IN 子句。 IN 等价于 ORIN上的很多iten意味着SQL上的很多OR,一般数据库很难优化。

如果查询仍然很慢,第二个要查找的地方是DISTINCTDISTINCT 有时可以通过 GROUP BY be replaced 获得性能提升。

【讨论】:

    猜你喜欢
    • 2016-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-10
    • 2021-07-22
    • 1970-01-01
    相关资源
    最近更新 更多