Loading
Salesforce에서 이메일을 보내기 위해서는 도메인 인증이 필요합니다.더 많이 읽기

'Apex CPU 시간 제한 초과'를 방지하기 위한 효율적인 코딩

게시 일자: Oct 13, 2022
상세 설명
Salesforce에는 CPU 사용량에 따라 트랜잭션에 대한 시간 제한이 있습니다. 트랜잭션에서 너무 많은 CPU 시간을 소모할 경우 장기 실행 트랜잭션으로 종료됩니다.
솔루션

당사에서는 응용 프로그램 서버 CPU 를 사용해야 하는 이벤트만 계산합니다. 앱 서버 CPU 를 사용하지만, 계산에 포함되지 않는 경우도 일부 존재합니다. 프로그래머로서 통제할 수 없는 사항은 포함되지 않습니다. 예를 들어 데이터베이스에서 레코드를 검색하는 데 소요된 시간은 포함되지 않습니다. 콜아웃이 반환될 때까지 대기하는 시간도 포함되지 않습니다. 코드에 컴파일이 필요한 경우, 이는 제어가 불가능하기에 해당 시간은 계산되지 않습니다.

상기 사항을 제외하면, 선언적 작업을 포함하여 응용 프로그램 서버에서 발생하는 거의 모든 사항이 계산에 포함됩니다. 코드의 DML에서 수식이 포함된 유효성 검사 규칙이 발견되면 해당 수식 평가에 소요된 시간을 계산합니다. CPU 시간은 하나의 Apex 트랜잭션에서 발생하는 Salesforce 응용 프로그램 서버의 모든 실행 대상 - 실행 중인 Apex 코드 및 이 코드에서 호출되는 패키지 코드와 워크플로 등의 모든 프로세스에 대해 계산됩니다. CPU 시간은 각 트랜잭션 별로 존재하며, 다른 트랜잭션과 격리됩니다. 응용 프로그램 서버 CPU 시간을 소비하지 않는 작업은 CPU 시간에 포함되지 않습니다.

계산되는 항목

  • 모든 Apex 코드
  • Apex에 노출된 라이브러리 기능
  • 워크플로 실행


계산되지 않는 항목

  • 데이터베이스 작업, 예: DML, SOQL, SOSL을 위해 데이터베이스에서 소비된 실행 시간 부분 및 Apex 콜아웃, SOQL을 위한 대기 시간은 계산되지 않습니다.
 

CPU 시간 초과를 줄이기 위한 모범 사례

Apex 코드 모범 사례를 참조하여 CPU 시간 초과를 줄일 수 있습니다. 아래에서 제안 사항 일부를 살펴보도록 하겠습니다. 
 

Map 기반 쿼리 사용

List<Account> lstacc=[Select Id from Account limit 10000]; Set<Id> setIds=new Set<Id>(); for(Account a:lstacc){ //More CPU time for sure due to looping setIds.add(a.id); } //Using Map query saves CPU time //Fetching all account in map Map<id,account> aMap = new Map<id,account>([Select Id,Name from Account limit 50000]); //Creating list of accounts List<account> accList = aMap.values() ; //Creating set of ids Set<id> accIds = aMap.keySet() ;


비즈니스 요건 상 비동기 작업 실행이 가능한지 확인

비즈니스와 관련된 처리가 실시간으로 실행되지 않아도 되는 경우가 있습니다. @future 를 이용한 코드 실행이 가능하다면, @future 는 컨텍스트를 벗어나도록 하게 할 것이며, CPU 타임아웃 제한치가 비동기 처리의 값인 60초 (동기 처리의 6배) 로 설정됩니다.
CPU 시간 한계에 도달할 위험이 있는 경우 이를 검토해주십시오.
 

집계 기능을 사용한 SOQL 이용

데이터베이스 시간은 CPU 시간으로 계산되지 않으므로 비즈니스 사용 사례에 대해 SOQL 집계 기능을 활용하는 것이 좋습니다.

일부 레코드의 필드 값 합계를 확인한다고 가정해보겠습니다. 일반 For 루프를 사용하여 이 값을 얻을 경우 확실히 CPU 시간이 소비되게 됩니다. 대신 데이터베이스 계층에서 SUM, AVG 집계 함수를 사용하여 계산을 하도록 방식을 변경해 보십시오. 이렇게 하면 데이터베이스 계층에서 처리하게 되며 CPU 시간을 단축하게 됩니다. 데이터베이스 계층에서 GROUP BY 혹은 일종의 필터링을 만드는 것을 검토해 주십시오. CPU 시간 초과 문제가 발생할 가능성을 줄일 수 있도록 데이터베이스 계층에서 계산 작업을 실행하도록 검토해 주십시오.

필요한 데이터만 가져와서 루프를 실행합니다.

레코드 목록에서 For를 수행하는 동안 특정 데이터만 필터링해야 합니다. 루핑이 너무 많을 경우 CPU 시간이 증가합니다. 이는 스크립트문 개수 제한이 있었던 시절에도 동일하게 적용되었습니다.

Knowledge 기사 번호

000387833

 
로드 중
Salesforce Help | Article