在Laravel中使用代码块或游标优化代码 [英] Optimizing code with chunk or cursor in laravel
问题描述
我在Laravel 5.4
应用程序中定义了Company
模型和Contact
模型,它们两者之间有许多关系.因此,例如联系人模型具有:
public function company()
{
return $this
->belongsToMany('App\Company', 'company_contact','contact_id', 'company_id')->withTimestamps();
}
现在我有一个数据集,我想在其中提取所有联系人数据以及公司详细信息,所以我在使用:
public function getData()
{
$contacts = Contact::all();
foreach($contacts as $contact)
{
$getCompany = $contact->company()->withPivot('created_at')->orderBy('pivot_created_at', 'desc')->first();
$getCompany->contacts = Company::find($getCompany->id)->contacts;
$contact->company = $getCompany;
$contact->companies_interested = json_decode($contact->companies_interested);
$companies = [];
if($contact->companies_interested)
{
foreach($contact->companies_interested as $companiesInterested)
{
$getCompany = Company::withTrashed()->find($companiesInterested);
$companies[] = array(
'value' => $getCompany->id,
'label' => $getCompany->name
);
}
$contact->companies_interested = json_encode($companies);
}
}
return response()->json([
'model' => $contacts
], 200);
}
这对于小型数据集非常适用,但是在使用大量数据时却失败了(大约10,000个字段),我想php memory fails
在涉及大型数据集时会加载.我正在浏览Laravel
文档以找出解决方案,并了解了chunk()
和cursor()
方法.有人可以指导我解决该问题的方法吗?或者可以采用什么方法来解决此问题.>
谢谢
我建议您对这两种方法进行一些系统古怪的测试.
块:
它将分页"您的查询,这样您就可以使用更少的内存.
- 使用更少的内存
- 需要更长的时间
`
public function getData() {
Contact::chunk(1000, function ($contacts) {
foreach ($contacts as $contact) {
//rest of your code...
}
});
}
`
光标:
您将使用PHP生成器逐一搜索查询项.
- 花费更少的时间
- 使用更多的内存
`
public function getData() {
foreach (Contact::cursor() as $contact) {
//rest of your code...
}
}
`
有关更详细的解释,请参见以下答案: https://translate.google.com/translate?hl=zh-CN&sl=auto&tl=en&u=http%3A% 2F%2Fqiita.com%2Fryo511%2Fitems%2Febcd1c1b2ad5addc5c9d
I'm having Company
Model and Contact
Model defined in my Laravel 5.4
application, both of them have many to many relationship. So, for example contacts model has:
public function company()
{
return $this
->belongsToMany('App\Company', 'company_contact','contact_id', 'company_id')->withTimestamps();
}
Now I've a data set where I want to pull all contacts data and there company details so I was using:
public function getData()
{
$contacts = Contact::all();
foreach($contacts as $contact)
{
$getCompany = $contact->company()->withPivot('created_at')->orderBy('pivot_created_at', 'desc')->first();
$getCompany->contacts = Company::find($getCompany->id)->contacts;
$contact->company = $getCompany;
$contact->companies_interested = json_decode($contact->companies_interested);
$companies = [];
if($contact->companies_interested)
{
foreach($contact->companies_interested as $companiesInterested)
{
$getCompany = Company::withTrashed()->find($companiesInterested);
$companies[] = array(
'value' => $getCompany->id,
'label' => $getCompany->name
);
}
$contact->companies_interested = json_encode($companies);
}
}
return response()->json([
'model' => $contacts
], 200);
}
This works perfectly fine for small data set, but while using large number of data it fails (approx 10,000 fields), I guess php memory fails
to load when it comes to large data set. I was going through Laravel
docs to find out the solution and came to know about chunk()
and cursor()
methods, Can someone guide me what can be done in this problem or what can be the approach to overcome this.
Thanks
I recommend you to test both methods for some quirkiness of your system.
Chunk:
It will "paginate" your query, this way you use less memory.
- Uses less memory
- It takes longer
`
public function getData() {
Contact::chunk(1000, function ($contacts) {
foreach ($contacts as $contact) {
//rest of your code...
}
});
}
`
Cursor:
You will use PHP Generators to search your query items one by one.
- It takes less time
- Uses more memory
`
public function getData() {
foreach (Contact::cursor() as $contact) {
//rest of your code...
}
}
`
For a more detailed explanation see this answer: What is the difference between laravel cursor and laravel chunk method?
For performance testing see this post: https://translate.google.com/translate?hl=en&sl=auto&tl=en&u=http%3A%2F%2Fqiita.com%2Fryo511%2Fitems%2Febcd1c1b2ad5addc5c9d
这篇关于在Laravel中使用代码块或游标优化代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!