优化慢速搜索多连接Oracle SQL查询Hibernate以获取高容量数据?

时间:2017-10-04 04:46:46

标签: oracle hibernate optimization query-optimization

首先,我们查看了几个与查询优化相关的问题和文档,这些问题和文档可能有助于解决这种情况,但我们仍然不清楚也不确定可能出现什么问题。

我们目前正在尝试寻找改进Hibernate查询搜索方法的最佳方法,当子表中涉及大量记录时,Hibernate会慢下来。所涉及的方法使用SQL调用至少四次:

  • a)搜索中的身份证(借款人)的清单 在开始日期之前选择了paymaster和处理 或在结束日期之后。 (这是可以接受的,因为它是一张桌子 搜索)

    b)搜索有效预订列表(已取消,新的,经过验证的, 但不得拒绝或解决)基于以上借款人名单

    c)搜索已停止预订的列表但仍处于活动状态 根据上述借款人名单处理。

注意:如果借款人少于1000,我们使用IN作为条件,否则,我们使用OR IN条件。

B和C的结果(它们在一个单一的函数中)被组合成另一个实体List作为CA.

d)CA列表中的每个实体在处理成文件之前都会受到呼叫金额生成功能的影响。

如果选择了多个paymaster,那么他们从A-D循环将再次与下一个paymaster一起开始。

上述过程涉及的四个主要表格,其中包含用于获取模式的连接用于子表: LoanFacility(主表) 通话金额(子表) 扣除代码(活跃借款人的每月扣除额表) 付款(为活跃借款人每月支付的子表)

借款人(用于B和C的边桌)

进行B和C的方法如下:

Criteria rootCriteria = session.createCriteria(LoanFacility.class);
rootCriteria.createAlias("fiBorrower", "fiBorrower");
setFetchModeForSubmissionFiles(rootCriteria);
rootCriteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);


//the work around for cases where there are more than 1000 borrowers
rootCriteria.add(QueryHelper.buildSplitCriterion("fiBorrower.icNumber",borrowerIcs.subList(first, max)));

            Conjunction andClause1 = Restrictions.conjunction();

            // we use statusForSubmission instead of submissionStatus because we
            // need to check previous status
            List<Integer> statusForSubmission = new ArrayList<Integer>();

            <Statuses from valid, processed, cancelled, etc..> excluding new, rejected and settled are added here>
            andClause1.add(Restrictions.in("status", statusForSubmission));

            if (processingDate != null) {
                Date endDate = DateUtil.getLastDate(processingDate);
                andClause1.add(Restrictions.le("commencementMonth", endDate));

                Conjunction andClause2 = Restrictions.conjunction();

                andClause2.add(Restrictions.isNotNull("reactivateCommencementDate"));
                andClause2.add(Restrictions.le("reactivateCommencementDate", endDate));

                rootCriteria.add(Restrictions.or(andClause1, andClause2));

            } else {
                rootCriteria.add(Restrictions.and(andClause1));
            }

            List<LoanFacility> allLoanFacilities = rootCriteria.list();
            for (LoanFacility loanfacility : allLoanFacilities) {
                LOG.info("Booking with ID in ori list: " + loanfacility.getBookingId());
                if (loanfacility.getStatus() == Constants.STATUS_BOOKING_PROCESSED
                        || loanfacility.getStatus() == Constants.STATUS_BOOKING_VALIDATED
                        || (loanfacility.getPreviousStatus() != null && loanfacility.getPreviousStatus().equals(Constants.STATUS_BOOKING_PROCESSED))
                        || (loanfacility.getPreviousStatus() != null && loanfacility.getPreviousStatus().equals(Constants.STATUS_BOOKING_VALIDATED) && loanfacility
                                .getStatus() != (Constants.STATUS_BOOKING_CANCELLED))
                        || (loanfacility.getPreviousBookingStatusLog() != null && StringUtils.contains(loanfacility.getPreviousBookingStatusLog(),
                                Constants.STATUS_BOOKING_PROCESSED.toString()))
                        || (loanfacility.getPreviousBookingStatusLog() != null
                                && StringUtils.contains(loanfacility.getPreviousBookingStatusLog(), Constants.STATUS_BOOKING_VALIDATED.toString()) && loanfacility
                                .getStatus() != (Constants.STATUS_BOOKING_CANCELLED))) {
                    loanFacilities.add(loanfacility);
                    LOG.info("Booking with ID added from ori list: " + loanfacility.getBookingId());

                }
            }

以下内容适用于已停止处理并处于活动状态的已停止预订:

Criteria stoppedBookingCriteria = session.createCriteria(LoanFacility.class);
                setFetchModeForSubmissionFiles(stoppedBookingCriteria);
                stoppedBookingCriteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

                stoppedBookingCriteria.createAlias("fiBorrower", "fiBorrower");
                //include booking where the stop date in the current processing month and status already settled
                List<Integer> statusForQueryStopBooking = new ArrayList<Integer>();
                Conjunction stopBookingAndClause1 = Restrictions.conjunction();
                Conjunction stopBookingAndClause2 = Restrictions.conjunction();
                stopBookingAndClause1.add(Restrictions.eq("status",Constants.STATUS_BOOKING_PROCESSED));
                stopBookingAndClause1.add(Restrictions.between("stoppedDate", DateUtil.getFirstDate(processingDate),
                        DateUtil.getLastDate(processingDate)));

                stopBookingAndClause2.add(Restrictions.eq("status",Constants.STATUS_BOOKING_SETTLED));
                stopBookingAndClause2.add(Restrictions.between("modifiedTime", DateUtil.getFirstDate(processingDate),
                        DateUtil.getLastDate(processingDate)));

                stoppedBookingCriteria.add(Restrictions.or(stopBookingAndClause1, stopBookingAndClause2));
                stoppedBookingCriteria.add(Restrictions.eq("activated", true));

                stoppedBookingCriteria.add(Restrictions.le("commencementMonth", DateUtil.getFirstDate(processingDate)));

                Criterion criterion = QueryHelper.buildSplitCriterion("fiBorrower.icNumber", borrowerIcs);
                stoppedBookingCriteria.add(criterion);
                List<LoanFacility> stoppedBookings = stoppedBookingCriteria.list();

在主实体对象上,子/子对象映射为:

@OneToMany(targetEntity = DeductionCode.class, fetch = FetchType.EAGER, cascade = {CascadeType.ALL})
    @JoinColumn(name = "facility_id", updatable = false)
    public Set<DeductionCode> getDeductionCodes() {
        return deductionCodes;
    }

 @OneToMany(targetEntity = FixedAllowance.class, fetch = FetchType.EAGER)
    @JoinColumn(name = "loan_facility_id", updatable = false)
    @NotAudited
    public Set<FixedAllowance> getFixedAllowances() {
        return fixedAllowances;
    }

@OneToMany(targetEntity = CallAmount.class, fetch = FetchType.LAZY)
    @JoinColumn(name = "loanfacility_id", updatable = false)
    @NotAudited
    public Set<CallAmount> getCallAmounts() {
        return callAmounts;
    }

我们已经对这些记录做了一些时间安排。拥有120多个预订或约7500多个付款和扣减记录的付款管理员需要花费35-40分钟的处理时间,而拥有约1700多条记录的付费主管需要大约8分钟(预订量最多的付费主管的五分之一) 。 300多个付款和扣减记录大约需要2-3分钟。我们的目标是将时间减少约30%。如果超过平均5分钟缓冲时间,我通常会中止。

如前所述,我没有找到可能与此方案相匹配的解决方案,因此,如果有提示或建议可以帮助改善此SQL块的性能,则会提前感谢。

更新1

Per @ Cyril要查看,这是从控制台中提取的Hibernate查询。条件方面,我从Criterion打印字符串中取出它。

select <fields from objects like Loan Facility, Call Account, Payment, etc>
            from
        LOAN_FACILITY this_ 
    left outer join
        APP_USER user3_ 
            on this_.assign_user=user3_.id 
    left outer join
        user_role roles4_ 
            on user3_.id=roles4_.user_id 
    left outer join
        ROLE role5_ 
            on roles4_.role_id=role5_.id 
    left outer join
        DEDUCTION_CODE deductionc6_ 
            on this_.id=deductionc6_.facility_id 
    left outer join
        LOAN_FACILITY loanfacili7_ 
            on deductionc6_.FACILITY_ID=loanfacili7_.id 
    left outer join
        FI_BORROWER fiborrower8_ 
            on loanfacili7_.fi_borrower_id=fiborrower8_.id 
    left outer join
        FINANCIAL_INSTITUTION financiali9_ 
            on fiborrower8_.fi_id=financiali9_.id 
    left outer join
        BANK bank10_ 
            on financiali9_.bank_id=bank10_.id 
    left outer join
        FI_TYPE fitype11_ 
            on financiali9_.FITYPE_CODE=fitype11_.code 
    left outer join
        FI_CLASSIFICATION ficlassifi12_ 
            on fitype11_.classification_code=ficlassifi12_.code 
    left outer join
        FINANCIAL_INSTITUTION financiali13_ 
            on financiali9_.parentFI_id=financiali13_.id 
    left outer join
        BANK bank14_ 
            on financiali13_.secondaryBank_id=bank14_.id 
    left outer join
        OCCUPATION occupation15_ 
            on fiborrower8_.occupation_id=occupation15_.id 
    left outer join
        OCCUPATION_CLASSIFICATION occupation16_ 
            on occupation15_.classification_id=occupation16_.id 
    left outer join
        FIXED_ALLOWANCE fixedallow17_ 
            on loanfacili7_.id=fixedallow17_.loan_facility_id 
    inner join
        FI_BORROWER fiborrower1_ 
            on this_.fi_borrower_id=fiborrower1_.id 
    where
        fiBorrower.icNumber in (<all the Id numbers here) or fiBorrower.icNumber in (850928146543), (status in (1, 2, 3, 4, 5, 6, 7, 8, 10) and commencementMonth <=Tue Oct 31 23:59:59 SGT 2017) or (reactivateCommencementDate is not null and reactivateCommencementDate <=Tue Oct 31 23:59:59 SGT 2017)])

更新2: 统计数据没有任何显着性。在该功能上,它仅显示以下内容:

Logging statistics....
Logging statistics....
Start time: 1508162337450
Start time: 1508162337450
Sessions opened: 0
Sessions closed: 0
Transactions: 0
Successful transactions: 0
Optimistic lock failures: 0
Flushes: 0
Connections obtained: 0
Statements prepared: 0
Statements closed: 0
Second level cache puts: 0
Second level cache hits: 0
Second level cache misses: 0
Entities loaded: 0
Entities updated: 0
Entities inserted: 0
Entities deleted: 0
Entities fetched (minimize this): 0
Collections loaded: 0
Collections updated: 0
Collections removed: 0
Collections recreated: 0
Collections fetched (minimize this): 0
NaturalId cache puts: 0
NaturalId cache hits: 0
NaturalId cache misses: 0
Max NaturalId query time: 0ms
NaturalId queries executed to database: 0
Queries executed to database: 0
Query cache puts: 0
update timestamps cache puts: 0
update timestamps cache hits: 0
update timestamps cache misses: 0
Query cache hits: 0
Query cache misses: 0
Max query time: 0ms

0 个答案:

没有答案