簡體   English   中英

Laravel減少查詢

[英]Laravel reducing queries

我使用Laravel Eloquent,我有這個代碼:

<?php
$bulk = Bulk::where('id', 'bulkid1');
echo $bulk->info;
foreach($bulk->models as $model) {
  echo $model->info;
  $lastreport = $model->reports()->getQuery()->orderBy('created_at', 'desc')->first();
  echo $lastreport->message;
}    
?>

我想要實現的是$lastreport是預加載的。 在這段代碼中,查詢將執行太多次(每個批量有1000個模型,導致1000個子查詢)。 雖然在普通的SQL中我可以這樣做:

SELECT * FROM bulk
LEFT JOIN models ON bulk.id = models.bulk_id
LEFT JOIN ( SELECT *, MAX(created_at) AS created_at
   FROM
     reports
   GROUP BY
     model_id )
lastreport ON models.id = lastreport.model_id
WHERE bulk.id = 'bulkid1'

數據庫偽代碼:

TABLE bulks
 id, info

TABLE models
id, bulk_id, info

TABLE reports
id, model_id, message

這是N + 1選擇問題這個問題的laravel解決方案是急切的加載

在你的情況下你會做:

<?php
$bulk = Bulk::with(['models', 'models.reports' => function ($query) { 
      return $query->orderBy('created_at', 'desc');           
   } 
])->where('id', 'bulkid1')->first();
echo $bulk->info;
foreach($bulk->models as $model) {
  echo $model->info;
  $lastreport = $model->reports->first();
  echo $lastreport->message;
}    

這應確保(a)所有模型僅加載1個附加查詢,(b)所有模型報告都加載了另一個附加查詢。 這樣做的缺點是,由於orderBy子句無法真正表示為查詢時間條件,因此加載的數據超出了必要的數量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM