在我的项目中,我将10000条记录插入表中。如果有任何记录,我们将使用休眠条件来获取它,并将其与新记录进行比较。表中的数据很少,大约有10000条记录。对于休眠标准,我们已经应用了条件。这个休眠标准是从表中获取6条记录。但是为什么我调用criteria.list()方法来获取6条记录会花费时间
休眠标准查询:
select this_.CLASS_TYPE as CLASS1_15_0_, this_.CLASS_UNIT_TYPE as CLASS2_15_0_, this_.CLASS_UNIT_CODE as CLASS3_15_0_,
this_.ID as ID15_0_, this_.LANG_CODE_ISO as LANG5_15_0_, this_.CTY_CODE_ISO as CTY6_15_0_, this_.NAME as NAME15_0_, this_.INS_DTIME as INS8_15_0_,this_.UPD_DTIME as UPD9_15_0_, this_.DEL_DTIME as DEL10_15_0_ from FI_SALES_LOCATION_V this_ where (this_.CLASS_TYPE='BU' and this_.CLASS_UNIT_TYPE='STO' and this_.CLASS_UNIT_CODE='A1000') and this_.DEL_DTIME is null and ((this_.LANG_CODE_ISO='en' and this_.CTY_CODE_ISO='GB' and this_.ID='A1000') or (this_.LANG_CODE_ISO='en' and this_.CTY_CODE_ISO='GB' and this_.ID='AP1000') or (this_.LANG_CODE_ISO='pt' and this_.CTY_CODE_ISO='PT' and this_.ID='AP1000') or (this_.LANG_CODE_ISO='pt' and this_.CTY_CODE_ISO='PT' and this_.ID='A1000') or (this_.LANG_CODE_ISO='s1' and this_.CTY_CODE_ISO='SI' and this_.ID='AP1000') or (this_.LANG_CODE_ISO='s1' and this_.CTY_CODE_ISO='SI' and this_.ID='A1000'));
答案 0 :(得分:0)
尝试以这种方式编写查询:
select this_.CLASS_TYPE as CLASS1_15_0_, this_.CLASS_UNIT_TYPE as CLASS2_15_0_, this_.CLASS_UNIT_CODE as CLASS3_15_0_,
this_.ID as ID15_0_, this_.LANG_CODE_ISO as LANG5_15_0_, this_.CTY_CODE_ISO as CTY6_15_0_, this_.NAME as NAME15_0_, this_.INS_DTIME as INS8_15_0_,this_.UPD_DTIME as UPD9_15_0_, this_.DEL_DTIME as DEL10_15_0_
from FI_SALES_LOCATION_V this_
where
(this_.CLASS_TYPE='BU' and this_.CLASS_UNIT_TYPE='STO' and this_.CLASS_UNIT_CODE='A1000')
and this_.DEL_DTIME is null
and (this_.LANG_CODE_ISO='en' and this_.CTY_CODE_ISO='GB' and this_.ID='A1000')
UNION ALL
select this_.CLASS_TYPE as CLASS1_15_0_, this_.CLASS_UNIT_TYPE as CLASS2_15_0_, this_.CLASS_UNIT_CODE as CLASS3_15_0_,
this_.ID as ID15_0_, this_.LANG_CODE_ISO as LANG5_15_0_, this_.CTY_CODE_ISO as CTY6_15_0_, this_.NAME as NAME15_0_, this_.INS_DTIME as INS8_15_0_,this_.UPD_DTIME as UPD9_15_0_, this_.DEL_DTIME as DEL10_15_0_
from FI_SALES_LOCATION_V this_
where
(this_.CLASS_TYPE='BU' and this_.CLASS_UNIT_TYPE='STO' and this_.CLASS_UNIT_CODE='A1000')
and this_.DEL_DTIME is null
and (this_.LANG_CODE_ISO='en' and this_.CTY_CODE_ISO='GB' and this_.ID='AP1000')
UNION ALL
select this_.CLASS_TYPE as CLASS1_15_0_, this_.CLASS_UNIT_TYPE as CLASS2_15_0_, this_.CLASS_UNIT_CODE as CLASS3_15_0_,
this_.ID as ID15_0_, this_.LANG_CODE_ISO as LANG5_15_0_, this_.CTY_CODE_ISO as CTY6_15_0_, this_.NAME as NAME15_0_, this_.INS_DTIME as INS8_15_0_,this_.UPD_DTIME as UPD9_15_0_, this_.DEL_DTIME as DEL10_15_0_
from FI_SALES_LOCATION_V this_
where
(this_.CLASS_TYPE='BU' and this_.CLASS_UNIT_TYPE='STO' and this_.CLASS_UNIT_CODE='A1000')
and this_.DEL_DTIME is null
and (this_.LANG_CODE_ISO='pt' and this_.CTY_CODE_ISO='PT' and this_.ID='AP1000')
UNION ALL
select this_.CLASS_TYPE as CLASS1_15_0_, this_.CLASS_UNIT_TYPE as CLASS2_15_0_, this_.CLASS_UNIT_CODE as CLASS3_15_0_,
this_.ID as ID15_0_, this_.LANG_CODE_ISO as LANG5_15_0_, this_.CTY_CODE_ISO as CTY6_15_0_, this_.NAME as NAME15_0_, this_.INS_DTIME as INS8_15_0_,this_.UPD_DTIME as UPD9_15_0_, this_.DEL_DTIME as DEL10_15_0_
from FI_SALES_LOCATION_V this_
where
(this_.CLASS_TYPE='BU' and this_.CLASS_UNIT_TYPE='STO' and this_.CLASS_UNIT_CODE='A1000')
and this_.DEL_DTIME is null
and (this_.LANG_CODE_ISO='pt' and this_.CTY_CODE_ISO='PT' and this_.ID='A1000')
UNION ALL
select this_.CLASS_TYPE as CLASS1_15_0_, this_.CLASS_UNIT_TYPE as CLASS2_15_0_, this_.CLASS_UNIT_CODE as CLASS3_15_0_,
this_.ID as ID15_0_, this_.LANG_CODE_ISO as LANG5_15_0_, this_.CTY_CODE_ISO as CTY6_15_0_, this_.NAME as NAME15_0_, this_.INS_DTIME as INS8_15_0_,this_.UPD_DTIME as UPD9_15_0_, this_.DEL_DTIME as DEL10_15_0_
from FI_SALES_LOCATION_V this_
where
(this_.CLASS_TYPE='BU' and this_.CLASS_UNIT_TYPE='STO' and this_.CLASS_UNIT_CODE='A1000')
and this_.DEL_DTIME is null
and (this_.LANG_CODE_ISO='s1' and this_.CTY_CODE_ISO='SI' and this_.ID='AP1000')
UNION ALL
select this_.CLASS_TYPE as CLASS1_15_0_, this_.CLASS_UNIT_TYPE as CLASS2_15_0_, this_.CLASS_UNIT_CODE as CLASS3_15_0_,
this_.ID as ID15_0_, this_.LANG_CODE_ISO as LANG5_15_0_, this_.CTY_CODE_ISO as CTY6_15_0_, this_.NAME as NAME15_0_, this_.INS_DTIME as INS8_15_0_,this_.UPD_DTIME as UPD9_15_0_, this_.DEL_DTIME as DEL10_15_0_
from FI_SALES_LOCATION_V this_
where
(this_.CLASS_TYPE='BU' and this_.CLASS_UNIT_TYPE='STO' and this_.CLASS_UNIT_CODE='A1000')
and this_.DEL_DTIME is null
and (this_.LANG_CODE_ISO='s1' and this_.CTY_CODE_ISO='SI' and this_.ID='A1000');
即使编写更多内容,执行UNION ALL而不是OR也会提高性能。
或者您可以为表建立索引,但是会降低INSERT的性能。
答案 1 :(得分:0)
考虑问题和评论中的信息,这就是代码的作用:
您必须了解休眠会话在某些情况下的行为。当您在休眠状态下执行操作时,您正在做的事情(在第一时间)是在更新休眠会话。无论是插入,删除还是更新,该操作都将在会话中执行,Hibernate甚至会记录一条SQL语句,但是它不会立即刷新到您的数据库中(是的,这具有误导性)。
通常情况下,所有内容都将被刷新并结束事务,但是在某些情况下,休眠将刷新操作以使会话保持最新状态。在您的情况下,您有多个记录要插入/合并,但是在执行每个操作之前,您都要执行选择。 Hibernate会检测到该操作,并将刷新每个先前存储的操作,这仅仅是因为查询数据库是否有待刷新的未决操作是没有意义的。数据库需要处于可能的最新状态。不要试图与之抗争,它是按照这种方式工作的。
所以我最好的猜测是,当您的选择花费太多时间执行时,这是因为休眠状态刷新了先前的插入/更新操作。
解决方法:
我想不出任何简单的方法来解决这个问题。您将不得不重新考虑您的方法。
有一件事很重要:即使您只需要纯插入而没有任何验证,您也会遇到一些麻烦,因为您的代码正在尝试插入数千条记录。这样做的最大问题是,就像我之前写的那样,休眠状态直到事务结束才刷新操作。因此,它将把每个要执行的语句保存在内存中。您很有可能会耗尽内存。
我要做的第一件事是检查批处理中的休眠文档(从docs开始)。之后,我将找出一种策略来优化插入大量记录和验证所需的需求。 不用处理单个记录,而可以处理数据块。
从可用的少量信息中,我将尝试以下工作流程:
在进行所有操作之前,请定义休眠的批处理大小属性(同样,请查看有关批处理的文档)
基本上,这是您正在执行的“相同”过程,但是它将对大块记录执行,而不是在每条记录中都执行。