我想知道是否有人可以就重构下面的函数来减少数据库查询的数量提出一些建议?或者,使用Laravel可能会有完全不同的方法来实现这一目标。
我正在尝试计算作业的P& L,它由产品组成,由产品组成:
public function jobProfitAndLoss($id)
{
$products_in_job = DB::table('job_product')
->where('job_id', $id)
->get();
$total_price = 0.0000;
$total_cost = 0.0000;
foreach ($products_in_job as $row) {
$total_price = $total_price + ($row->quantity)*($row->price);
$product_id = $row->product_id;
$components_in_product = DB::table('components')
->where('product_id', $product_id)
->get();
foreach ($components_in_product as $component) {
$total_cost = $total_cost + ($component->cost)*($row->quantity);
}
}
return $total_price-$total_cost;
}
产品有组件 -
https://www.dropbox.com/s/ncnij8dnh99sb9v/Screenshot%202016-04-09%2015.22.26.png?dl=0
组件属于产品 -
https://www.dropbox.com/s/3dx6u30gbod2rv4/Screenshot%202016-04-09%2015.23.43.png?dl=0
乔布斯有很多产品 -
https://www.dropbox.com/s/q179t0knd7y8z4k/Screenshot%202016-04-09%2015.24.11.png?dl=0
你会在这里看到有一些相同的查询被多次执行,我不知道在这种情况下如何避免 -
https://www.dropbox.com/s/xonbtx9cdqvq1wd/Screenshot%202016-04-09%2015.33.07.png?dl=0
非常感谢任何帮助。
答案 0 :(得分:1)
编辑:您似乎没有使用模型。如果尚未执行此操作,请为数据库条目创建模型。您需要使用protected $table
的{{1}}属性,因为Eloquent可能无法自动将您的类名转换为正确的表名。
首先,如果你还没有这样做,建立关系。例如,在job_product
下,包含产品关系:
Job.php
现在,您可以直接执行public function products() {
return $this->hasMany(App\Products::class); // Assuming App is the namespace
}
,而不是使用$ components_in_product的Fluent查询。但是,这仍然导致N + 1个查询。
因此,请看一下:https://laravel.com/docs/5.2/eloquent-relationships#eager-loading
$components_in_product = $products_in_job->products;
对于此操作,将只执行两个查询:
$books = App\Book::with('author')->get(); foreach ($books as $book) { echo $book->author->name; }
因此,将select * from books
select * from authors where id in (1, 2, 3, 4, 5, ...)
更改为Eloquent查询并将$products_in_job
添加到查询中。