【问题标题】:MySQL JPA query with large number of columns runs much slower than expected具有大量列的 MySQL JPA 查询运行速度比预期慢得多
【发布时间】:2019-01-14 09:57:38
【问题描述】:

当我通过 JPA 执行查询时,查询运行缓慢,普通的 mysql 调用需要 ~0.05 秒,通过 JPA 需要 3 秒以上,我不明白为什么。 记录器显示,它有很长的 ObjectBuildingTime:

    number of objects=953,
total time=2673045667,
local time=2673045667,
profiling time=1273000,
Timer:Logging=616666,
Timer:ObjectBuilding=2317873662,
Timer:SqlPrepare=16289334,
Timer:Register=149633998,
Timer:StatementExecute=82975667,
Timer:Caching=82966350,
Timer:RowFetch=223775000,
time/object=2804874,

这是什么意思,我该如何加快速度? 我的查询如下所示:

SELECT * FROM TESTENTITY t0, INNERTESTENTITY t1 WHERE (((t0.TIMESTAMPCREATION BETWEEN ? AND ?) AND (t0.DATA_TYPE IS NOT NULL)) AND ((t1.ID = t0.ID)))

Innertestentity 有许多属性 (~40) 和两个指向其他较小对象的 ForeignKey。它是来自 Testentity 的映射超类。这可能是原因吗? 提前感谢您的帮助。

编辑: 我的实体看起来像

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "DATA_TYPE")
public class TestEntity{
    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
    @JoinColumn(name = "Employee_ID")
    private EmployeeEntity employeeEntity;

@Entity
@MappedSuperclass
@DiscriminatorValue("SURVEYDATA")
public class innertestEntity extents TestEntity{
    private List<Integer> counts;
    @ElementCollection
    @MapKeyColumn(name = "statename")
    @Column(name = "value")
    @CollectionTable(name = "states")
    private List<Integer> states;
    private List<String> namelist;

【问题讨论】:

  • 你能检查一下你的抓取策略吗?懒惰还是渴望?这可能是问题
  • 跟随 Echo 的评论。急切加载相关实体(那些外键)会将查询转换为from testentity left join foreigntable1 left join foreigntable2
  • 我刚刚编辑了我的问题。据我了解,我只与 EmployeeEntity 有关系,它有 fetchType.Lazy
  • 打开日志以查看在构建结果时生成的 SQL 查询。将元素集合到另一个表也不会过于高效,但这完全取决于您的数据库环境/数据/调整等。您可以尝试使用 batchFetch 注释 (eclipse.org/eclipselink/documentation/2.5/jpa/extensions/…) 和/或查询提示来减少数量对该表的查询,但必须测试最适合您的应用程序的方法。
  • 你能写下生成了什么sql查询吗?是否可以将其简化为表中列较少的完整示例?您的测试查询是做与 JPA 查询相同的工作量,还是获取更多数据,例如加入其他表?你的键有索引吗?

标签: java mysql jpa eclipselink jpql


【解决方案1】:

尝试在日志中打开 SQL 查询调试,看看它是否告诉您任何有趣的信息,在您的 application.properties 中:

org.hibernate.SQL=DEBUG

您也可以尝试在您的 MySQL 配置文件(可能是 /etc/my.cnf )中打开 MySQL 的慢查询日志,这也可能提供信息:

slow-query-log                  = 1
slow-query-log-file             = /var/lib/mysql/mysql-slow.log

我怀疑问题可能是正在加载其中一些其他对象(如 EmployeeEntity)(如果您的代码正在访问这些字段,则可能是这种情况)。在这些日志和您的代码之间,我想您会看到是否正在访问和加载更多内容。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-28
    • 2011-09-20
    • 1970-01-01
    相关资源
    最近更新 更多