Salesforce 如何替换嵌套for循环映射,以及如何减少计算部分的时间?

Salesforce 如何替换嵌套for循环映射,以及如何减少计算部分的时间?,salesforce,Salesforce,如何用map替换嵌套for循环 如何用映射替换嵌套的FOR循环 公共类案例{ public void calculatetimeList caseids,Map casemap{ map<string,List<CaseMilestone>> milestonemap = new map<string,List<CaseMilestone>>(); if(casemap!=null && caseids.size()

如何用map替换嵌套for循环

如何用映射替换嵌套的FOR循环

公共类案例{ public void calculatetimeList caseids,Map casemap{

    map<string,List<CaseMilestone>> milestonemap = new map<string,List<CaseMilestone>>();
    if(casemap!=null && caseids.size()>0){
        BusinessHours bh = [SELECT Id FROM BusinessHours WHERE IsDefault=true];
        List<Case> caselist = [Select id, (select caseId,id,isCompleted,MilestoneTypeId,BusinessHoursId,MilestoneType.name,CompletionDate from 
                                           CaseMilestones where(MilestoneType.name='First Response' or MilestoneType.name='Technical Resolution')
                                           AND caseid IN:casemap.keySet()) from case]; 

        for(Case cs: caselist ){
            milestonemap.put(cs.id,cs.Casemilestones);
        }
        for(Case c: caseids){
            if(c.Request_for_Closure_Date__c!=null && milestonemap.containskey(c.id) ){
                for(CaseMilestone ml:milestonemap.get(c.id)){
                    if(ml.MilestoneType.name=='First Response'){
                        Integer ms = Integer.valueOf((BusinessHours.diff(bh.id, ml.CompletionDate, c.Request_for_Closure_Date__c))/1000);
                        system.debug('Time@calculation'+ms);
                        Integer sec = ms;
                        Integer mns = sec/60;
                        integer days = mns / 60 / 24 ;
                        integer hours = (mns - days * 60 * 24) / 60 ;
                        integer mins = mns - days * 60 * 24 - hours * 60 ;
                        String timeSpentOnCase = days+'Days '+hours+'Hours '+mins+'Minutes'+sec+'Secs';
                        System.debug('Time'+timeSpentOnCase);

                        c.Test_Ignore__c = ml.CompletionDate;
                    }
                    else if(ml.MilestoneType.name=='Technical Resolution'){
                        c.Test_Ignore_2__c = ml.CompletionDate;
                    }
                }
            }
        }
    }
}

}

这些循环已经过优化,但实际上不需要基于地图的数据访问,因为子对象是通过父对象查询的

    for(Case cs: caselist ){
        milestonemap.put(cs.id,cs.Casemilestones);
    }
这完全不需要,可以删除。相反,更改内部for循环以直接引用子事例里程碑列表

    for(Case c: caseids){
        if(c.Request_for_Closure_Date__c!=null){
            for(CaseMilestone ml : c.CaseMilestones){
如果c.case为空,循环就不会执行


这段代码没有进一步的基于地图的优化。

正如David在上面的评论中所说的,访问已经相当优化了。 如果您寻求进一步优化,我会:

移动ifc.Request\u for\u Closure\u Date\u c!=null并改进WHERE子句,如果在处理过程中跳过某些案例,为什么要检索它们

SELECT Id,
    (SELECT CaseId, Id, isCompleted...
    FROM CaseMilestones
    WHERE ...)
FROM Case
WHEREId IN :caseids AND Request_for_Closure_Date__c!=null    
扔掉这些代码。如果只是为了system.debug,那就是在浪费计算时间

Integer ms = Integer.valueOf((BusinessHours.diff(bh.id, ml.CompletionDate, c.Request_for_Closure_Date__c))/1000);
system.debug('Time@calculation'+ms);
Integer sec = ms;
Integer mns = sec/60;
integer days = mns / 60 / 24 ;
integer hours = (mns - days * 60 * 24) / 60 ;
integer mins = mns - days * 60 * 24 - hours * 60 ;
String timeSpentOnCase = days+'Days '+hours+'Hours '+mins+'Minutes'+sec+'Secs';
System.debug('Time'+timeSpentOnCase);
如果在这两次优化之后,您仍然存在性能问题,那么您可能必须重新考虑您的业务逻辑和查询。是否保证每种情况下最多有一个里程碑

也许您需要一个只包含一种类型的子查询来提供最新的里程碑?类似于选择Id,从CaseModels中选择CompletionDate,其中type='x'ORDER BY CompletionDate DESC LIMIT 1 FROM Case?然后您对第二种类型和流程运行此查询。好的,浪费2个查询,但保证只返回几行

或者,您可以通过执行以下操作完全简化此代码

SELECT CaseId, MAX(CompletionDate) d, MilestoneType.Name t
FROM CaseMilestone
WHERE CaseId IN :... AND MilestoneType.Name IN :...
GROUP BY CaseId, MilestoneType.Name

谢谢你们两位,如果case没有任何里程碑,我如何修改我的代码以停止执行查询。在最初的一个查询之后,您没有进行任何查询。我不确定您在问什么。如果我的case没有里程碑,我如何停止执行这两个查询。如何提前检查。您的意思是传递给函数的参数?modify t他查询说SELECT Id,…FROM Case WHERE…和SELECT CaseId FROM CASEMENTOLLESTONE中的Id。它应该可以很好地立即过滤掉相关列表中没有任何内容的情况。如果这仍然会给您带来性能问题-有些严重错误,但可能在其他地方。您必须在调试日志中计时,以查看真正的问题在哪里瓶颈是。如果我的案例没有任何里程碑,并且“请求关闭日期”或“技术解决方案”或“固定日期”被更改,我的查询将运行。是否有方法停止执行这些查询