gpt4 book ai didi

php - 如何在 Laravel Eloquent handy appends 上提高数据库性能?

转载 作者:行者123 更新时间:2023-11-29 03:22:07 27 4
gpt4 key购买 nike

所以 Laravel 的 $appends 是一个非常好的特性。我有一个 products 表,我将 vendorimages 和其他添加到 $appends 数组,所以我的代码如下所示:

类产品扩展\ResourceModel {

protected $appends = ['vendor', 'images'];

function getVendorAttribute() {
return $this->vendor()->first();
}

function getImages() {
$this->_images = $this->images()->get();
}

整洁吧?

但是,不是那么快,这里是这段简洁的代码正在执行的查询列表:

select * from `products`;
select * from `images` where `images`.`imageable_id` = 1 and `images`.`imageable_type` = 'Product';
select * from `vendors` where `vendors`.`id` = 1;
select * from `images` where `images`.`imageable_id` = 2 and `images`.`imageable_type` = 'Product';
select * from `vendors` where `vendors`.`id` = 2;
select * from `images` where `images`.`imageable_id` = 3 and `images`.`imageable_type` = 'Product';
select * from `vendors` where `vendors`.`id` = 3;
select * from `images` where `images`.`imageable_id` = 4 and `images`.`imageable_type` = 'Product';
select * from `vendors` where `vendors`.`id` = 4;
select * from `images` where `images`.`imageable_id` = 5 and `images`.`imageable_type` = 'Product';
select * from `vendors` where `vendors`.`id` = 5;

当然,我宁愿这样做:

select * from `products`;
select * from `images` where `images`.`imageable_id` in (1, 2, 3, 4, 5) and `images`.`imageable_type` = 'Product';
select * from `vendors` where `vendors`.`id` in(1, 2, 3, 4, 5);

或者甚至是 JOIN 等价物。

所以,我的问题很详细:

1) 我以 20 页为单位加载产品。这生成了大约 41 个查询(更确切地说,我为了这个问题简化了它)。我认为这真的会损害性能,对吗?对于一个普通的 MySQL 框来说,第一种类型的 41 个简单查询确实比第二种类型的 3 个查询更耗时?

2) 在我疯狂修复我所有的应用程序逻辑之前,是否有一种捆绑(或打包,或简单)的方式在 Laravel 上执行此操作?

提前致谢!

最佳答案

问题是您的方法正在使用关系查询,因此每次访问它们时都会运行一个新查询,并且没有利用任何延迟加载或急切加载。

你可以通过确保预先加载你的关系并访问关系属性($this->vendor vs $this->vendor())来解决这个问题方法,但您需要重命名您的 getVendorAttribute() 方法,使其不与关系属性冲突。

但是,我认为您可能正在寻找模型上的 $with 属性。如果您在模型上设置了 $with 属性,则该属性列出的关系将始终为该模型预先加载。此外,由于关系将始终存在,因此当模型转换为数组时它们将始终存在,并且无需向您的 $appends 属性添加任何内容。

所以,你的类看起来像这样:

class Product extends Model {

// always eager load the vendor and images relationships
protected $with = ['vendor', 'images'];

// relationship to the vendor
public function vendor()
{
return $this->belongsTo(Vendor::class);
}

// relationship to the images
public function images()
{
return $this->hasMany(Image::class);
}
}

对于上面的类,如果您要在加载的 Product 实例上调用 toArray()toJson(),输出将包括相关的 vendor 和相关的 images

如需进一步阅读,我建议阅读 relationship methods vs propertieseager loading .

关于php - 如何在 Laravel Eloquent handy appends 上提高数据库性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42544284/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com