简体   繁体   中英

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. 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.

Is it safe to assume that 98% of the time is used for mapping those results to their corresponding entities? 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 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. 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.

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...
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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