php
  • laravel
  • laravel-5
  • eloquent
  • 2016-10-24 6 views 1 likes 
    1

    다음 쿼리는 큰 데이터 집합 (~ 25k 행)을 검색합니다. 그것은 매우 느리게 실행되고, 나는 그것을 속도를하는 방법을 알고 싶습니다어떻게이 질의 응답을 빠르게 할 수 있습니까?

    $jobs = Job::whereArchived(true)->get(); 
    
        foreach ($jobs AS $job) 
        { 
         $rows[] = [ 
          "<a href='/admin/projects/jobs/$job->id'>{$job->name}</a>", 
          $job->start_date ? $job->start_date : "Not Specified", 
          $job->end_date ? $job->end_date : "Not Specified", 
          $job->agent ? $job->agent->name : "Unassigned", 
          $job->status ? $job->status : "Not Specified" 
    
         ]; 
        } 
    echo Html::table() 
        ->head($headers) 
        ->body($rows) 
        ->datatable(); 
    

    이 특정 쿼리/결과는 적어도 완료하는 데 약 60 초가 걸립니다. 어떻게 속도를 높일 수 있습니까? 당신이> 에이전트을 $으로 일자리를 액세스 할 때

    답변

    1

    당신은 다른 모든 작업 기록 추가 쿼리 실행, 부하가 에이전트 모델 관련 열심히해야합니다.

    $jobs = Job::with('agent')->whereArchived(true)->get(); 
    

    $jobs = Job::whereArchived(true)->get(); 
    

    를 교체하고 당신은 쿼리 성능에서 상당한 개선을 볼 수 있습니다.

    논리가 여전히 너무 오래 걸리면 Eloquent 레이어를 완전히 건너 뛸 수 있습니다. 쿼리를 실행하는 데 많은 시간이 걸리는 또 다른 이유는 Eloquent 모델을 사용하여 데이터를 가져 오는 것입니다 - 데이터베이스에서 가져온 모든 행에 대해 작업의 개체를 만들어야하기 때문에.

    데이터를 배열로 가져 와서 개체를 생성하는 논리를 건너 뛰면 많은 양의 데이터를 처리하는 것이 더 효율적입니다. 당신은 DB 외관를 사용하여 데이터를 가져 오는하여 해당 작업을 수행 할 수 있습니다뿐만 아니라 상당한 성능 향상을 제공한다

    $jobs = DB::table('jobs')->where('archived', '=', true)->join('agents', 'jobs.agent_id', '=', 'agents.id')->get(); 
    

    .

    또 다른 이유는 필요한 것만 데이터베이스 대신 사용할 수있는 모든 열을 가져 오는 것이므로 데이터베이스에서 응용 프로그램으로 데이터를 전송하는 데 필요한 메모리 사용량과 시간이 늘어납니다. 당신은 그 열이로드 있도록 거 필요가있어 열 목록을 지정하여이 문제를 해결할 수 있습니다 : 마지막으로

    $jobs = Job::with('agent')->whereArchived(true) 
        ->get(['name', 'start_date', 'end_date', 'status']); 
    
    $jobs = DB::table('jobs')->where('archived', '=', true) 
        ->join('agents', 'jobs.agent_id', '=', 'agents.id') 
        ->get(['name', 'start_date', 'end_date', 'status']); 
    

    , 당신은 정말 한 번에 모든 레코드를 표시 할 필요가 있는지 생각합니다. 보통 필요하지 않으며 페이지가 매겨진 결과가 대신 표시 될 수 있습니다. https://laravel.com/docs/5.3/pagination

    1

    with() 함수를 사용하여 다른 대답에 지정된대로로드 할 수 있습니다. 그러나 단일 쿼리에서 25k 결과를 가져 오는 것은 좋은 방법이 아닙니다. 페이지 매김은이 상황에 적합한 후보이며 아약스를 사용하여 나머지 페이지를 가져올 수 있습니다. 페이지 매김이 옵션이 아닌 경우 '아카이브 된'열을 인덱싱하고 열심히로드하여 결과를 가져 오도록하십시오. 쿼리 성능이 크게 향상됩니다.

    관련 문제