由于使用Hibernate JPA时从实体中获取大约30k的结果会导致性能问题,因此我改写了namedQuery以更好地控制查询及其运行时间。我最终得到的只是这几个实体将近20秒,而那20秒对于“旧”查询和我自己的namedQuery是必需的(在sql客户端中执行时不需要一秒钟即可得到结果) ,因此基本上无论我使用namedQuery还是hibernate生成的查询都没有任何区别。
是否可以安全地假设98%的时间用于将那些结果映射到其对应的实体?如果是这样,我应该如何加快速度?以下是我自己编写的查询(请注意,我必须明确声明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
答案 0 :(得分:0)
编写原始sql与让hibernate / jpa为您完成操作并不能提高性能。原因可能是您的对象映射到其他对象(映射到其他对象,而不是懒惰)(因此,渴望获取),因此您可能会提取整个数据库。您可能会认为查询是唯一要执行的查询,但现实是其他映射可能正在创建/执行更多的sql查询...以我为例,对于10,000行执行映射的过程自己花费了100毫秒,但让hibernate / jpa进行了映射花了10秒,是整个100倍。
提高性能的是自己进行映射。像这样:
@Query(nativeQuery = true, value = "your_raw_sql_here")
List<Object[]> yourNativeQueryMethod();
然后您可以自己映射对象:
for( Object[] objectArray: results) {
BigInteger id = (BigInteger) objectArray[0];
//etc...
}