2016-10-24 57 views
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::whereArchived(true)->get(); 

$jobs = Job::with('agent')->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

您可以渴望的負載相關型號()函數使用在其他的答案中指定,但在一個查詢中獲取25K的結果是不是一個好方法。分頁是這種情況的良好候選者,您可以使用ajax來獲取其餘頁面。 如果分頁不是一個選項,供您然後嘗試索引中的列「歸檔」,並使用預先加載來獲取結果。它將顯着提高查詢性能。