简体   繁体   English

快速的JPA查询,但映射到实体的速度较慢

[英]Fast JPA Query but slow mapping to entity

Because of performance issues with fetching about 30k results from DB as entities when using Hibernate JPA, i instead tried to write a namedQuery to have more control over the query and its runtime. 由于使用Hibernate JPA时从实体中获取大约30k结果的性能问题,我改为尝试编写namedQuery以更好地控制查询及其运行时间。 What i end up with is almost 20 seconds just for those few entities, and those 20 seconds are necessary for the "old" query and my own namedQuery (which doesn't take a second to get the result when executed in a sql client), so basically it doesn't make any difference whether i use a namedQuery or the hibernate-generated query. 我最终得到的只是这几个实体将近20秒,而那20秒对于“旧”查询和我自己的namedQuery是必需的(在sql客户端中执行时不需要一秒钟即可得到结果) ,因此基本上无论我使用namedQuery还是hibernate生成的查询都没有任何区别。

Is it safe to assume that 98% of the time is used for mapping those results to their corresponding entities? 是否可以安全地假设将98%的时间用于将那些结果映射到其对应的实体? And if so, how should i speed this up? 如果是这样,我应该如何加快速度? Below is the query that i wrote myself (note that i explicitly have to state all the columns in the SELECT) 以下是我编写的查询(请注意,我必须明确声明SELECT中的所有列)

SELECT exp.ID
  ,exp.CREATEDBY
  ,exp.CREATEDTIME
  ,exp.DELETED
  ,exp.LASTCHANGE
  ,exp.LASTCHANGEBY
  ,exp.STATUS
  ,exp.BRIXFIGURE
  ,exp.GRAMMAGE
  ,exp.INDIVIDUALPACKAGING
  ,exp.MINORDERQUANTITY
  ,exp.PACKAGINGHEIGHT
  ,exp.PACKAGINGLENGTH
  ,exp.PACKAGINGWIDTH
  ,exp.PALETTESIZE
  ,exp.QUANTITY
  ,exp.UNIT
  ,exp.VALIDUNTIL
  ,exp.EXPORTELEMENT_START
  ,exp.EXPORTSTATUS
  ,exp.webServiceResponse
  ,exp.CATEGORYID
  ,exp.COMMENTID
  ,exp.SUPPLIERID
  ,exp.TRANSPORTPACKAGINGID
  ,exp.LocationId
  ,exp.PriceRowId
  ,exp.EXPORTELEMENT_ENDDATE
  ,exp.BASEPRICE
  ,exp.BASEUNIT
  ,exp.BARCODES
  ,exp.EXPIRYDATE
  ,exp.PREORDERPERIOD
  ,exp.EXPORTWEEKID
  ,exp.EXPORT_TENDER_UID
  ,exp.EXPORT_UID
  ,exp.CURRENCY_ID
  ,exp.WEIGHT_PER_BOX
  FROM EXPORTELEMENT AS exp
  JOIN EXPORTELEMENT_LOCATION as exlo ON exlo.EXPORTELEMENTID = exp.ID
  WHERE exlo.LOCATIONID = :locationId
  AND exp.EXPORTELEMENT_ENDDATE <= :endDate
  AND exp.EXPORTELEMENT_START >= :startDate
  AND exp.DELETED = :deleted

Writing raw sql vs. letting hibernate/jpa do it for you doesn't improve the performance. 编写原始sql与让hibernate / jpa为您完成操作并不能提高性能。 The reason might be that your object is mapped to other objects (Fetch eager as opposed to lazy) that map to other objects etc...So you could potentially be pulling your whole db. 原因可能是您的对象映射到其他对象(映射到其他对象,而不是懒惰)(因此,渴望获取),因此您可能会提取整个数据库。 You might think your query is the only one being executed, but reality is the other mappings might be creating/executing more sql queries...In my case for 10,000 rows doing the mapping myself took 100 milliseconds, but letting hibernate/jpa do the mapping took 10s, a whole 100x. 您可能会认为查询是唯一要执行的查询,但现实是其他映射可能正在创建/执行更多的sql查询...以我为例,对于10,000行执行映射的过程自己花费了100毫秒,但让hibernate / jpa进行了映射花费了10秒,是整个100倍。

What improves the performance is doing the mapping yourself. 提高性能的是自己进行映射。 Something like this: 像这样:

@Query(nativeQuery = true, value = "your_raw_sql_here")
List<Object[]> yourNativeQueryMethod();

Then you can map the object yourself: 然后,您可以自己映射对象:

for( Object[] objectArray: results) {
    BigInteger id = (BigInteger) objectArray[0];
    //etc...
}

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM