我正在开发一个 Web (Laravel) 和 iOS 应用程序,它们都使用我也在使用 Laravel 开发的 REST API。来自托管在 AWS RDS 实例上的 MySQL 数据库的 API 查询。
当我在本地主机上同时设置 API 和应用程序,并将 API 配置为连接我的本地数据库(与应用程序和 API 在同一台机器上)时,它按预期工作正常,但问题出在我设置 API 时从 AWS RDS 数据库而不是本地查询。 用 Eloquent 方式进行简单的查询,比如
Product::where('brand_id', '=', $id)
->get()
大约需要 10 - 15 分钟才能完成,但是如果我使用查询生成器执行相同的查询,例如;
DB::select('select * from products where brand_id = ?', [$id]);
工作正常。
直接在 MySQL 上执行查询或在 Laravel Tinker 上运行 Product::all() 可以按预期使用本地 API/远程数据库设置。
编辑:
这是我执行 SHOW CREATE TABLE products
时得到的结果
CREATE TABLE `products` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`SKU` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`price` double(8,2) NOT NULL,
`description` text COLLATE utf8mb4_unicode_ci NOT NULL,
`product_details` text COLLATE utf8mb4_unicode_ci NOT NULL,
`material_and_care` text COLLATE utf8mb4_unicode_ci NOT NULL,
`material` text COLLATE utf8mb4_unicode_ci NOT NULL,
`care` text COLLATE utf8mb4_unicode_ci NOT NULL,
`colors` text COLLATE utf8mb4_unicode_ci NOT NULL,
`made_in` text COLLATE utf8mb4_unicode_ci NOT NULL,
`size_chart` text COLLATE utf8mb4_unicode_ci,
`size_chart_url` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`brand_id` int(10) unsigned NOT NULL,
`category_id` int(10) unsigned NOT NULL,
`published` tinyint(1) NOT NULL DEFAULT '0',
`featured` tinyint(1) NOT NULL DEFAULT '0',
`promo_title` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`promo_caption` text COLLATE utf8mb4_unicode_ci NOT NULL,
`shipping_height` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`shipping_width` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`shipping_length` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`shipping_weight` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`is_vertical` tinyint(1) NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
`deleted_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `products_category_id_foreign` (`category_id`),
KEY `products_brand_id_foreign` (`brand_id`),
CONSTRAINT `products_brand_id_foreign` FOREIGN KEY (`brand_id`) REFERENCES `brands` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `products_category_id_foreign` FOREIGN KEY (`category_id`) REFERENCES `subcategories` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=501 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
我的产品型号:
class Product extends Model
{
use SoftDeletes, CascadeSoftDeletes;
protected $cascadeDeletes = [
'items',
'options',
'images',
'sizes'
];
protected $fillable = [
'sku',
'name',
'price',
'description',
'product_details',
'material_and_care',
'material',
'color_1',
'color_2',
'color_3',
'care',
'made_in',
'size_chart',
'size_chart_url',
'brand_id',
'category_id',
'published',
'featured',
'promo_title',
'promo_caption',
'shipping_weight',
'shipping_height',
'shipping_width',
'shipping_length',
'is_vertical'
];
protected $appends = [
'interests',
'brand',
'options',
'sizes',
'items',
'images',
'comment_count',
'discount',
'suits_me_count'
];
protected $hidden = [
'created_at',
'deleted_at',
'updated_at',
'subcategory'
];
protected static function boot()
{
parent::boot();
static::addGlobalScope(new PublishedProductScope);
}
public function getDiscountAttribute() {
return $this->discount()->first();
}
public function getSuitsMeCountAttribute() {
return $this->suitsmes()->count();
}
public function getCommentCountAttribute() {
return $this->comments()->count();
}
public function getImagesAttribute(){
return $this->images()->pluck("url");
}
public function getInterestsAttribute() {
return $this->interests()->get();
}
public function getBrandAttribute(){
return $this->brand()->first();
}
public function getOptionsAttribute(){
return $this->options()->get();
}
public function getSizesAttribute(){
return $this->sizes()->get();
}
public function getItemsAttribute(){
return $this->items()->get();
}
public function interests() {
return $this->belongsToMany('App\Interest', 'product_interest');
}
public function brand() {
return $this->belongsTo('App\Brand');
}
public function options() {
return $this->hasMany('App\ProductOption');
}
public function sizes() {
return $this->hasMany('App\ProductSize');
}
public function items() {
return $this->hasMany('App\ProductItem');
}
public function images() {
return $this->hasMany('App\ProductImage');
}
public function comments() {
return $this->hasMany('App\ProductComment');
}
public function suitsmes() {
return $this->belongsToMany('App\User', 'wishlist', 'product_id', 'user_id');
}
public function discount(){
return $this->hasOne('App\Discount');
}
public function category() {
return $this->belongsTo('App\Subcategory', 'category_id');
}
}
还有我的品牌模型:
class Brand extends Model
{
protected $fillable = [
'first_name',
'last_name',
'email',
'phone_number',
'birth_date',
'ssn',
'street_address',
'street_address_2',
'city_address',
'state_address',
'postal_code_address',
'legal_name',
'dba',
'tax_id',
'street_business_address',
'street_business_address_2',
'city_business_address',
'state_business_address',
'postal_code_business_address',
'destination_fund',
'email_business',
'phone_number_business',
'account_number_fund',
'routing_number_fund'
];
protected $hidden = [
'created_at',
'deleted_at',
'updated_at'
];
protected $appends = [
'images'
];
public function getImagesAttribute()
{
return $this->images()->get();
}
public function getBillboardPicturesAttribute() {
$pictures = [$this->billboard, $this->billboard2, $this->billboard3, $this->billboard4];
return $pictures;
}
public function users()
{
return $this->belongsToMany('App\User', 'user_brand_role', 'brand_id', 'user_id');
}
public function getInterestsAttribute() {
return $this->interests()->pluck('interest_id');
}
public function interests() {
return $this->belongsToMany('App\Interest', 'brand_interest', 'brand_id', 'interest_id');
}
public function products() {
return $this->hasMany('App\Product');
}
public function images() {
return $this->hasMany('App\BrandImage');
}
public function categories() {
return $this->hasMany('App\Category');
}
public function getCatalogAttribute() {
return $this->categories()->orderBy('name', 'asc')->get();
}
}
最佳答案
问题是您的 Product
模型中的这段代码:
protected $appends = [
'interests',
'brand',
'options',
'sizes',
'items',
'images',
'comment_count',
'discount',
'suits_me_count'
];
These properties are relationships, and so they result in multiple joins every time Eloquent reads/returns a row.
此查询:DB::select('select * from products where brand_id = ?', [$id]);
不会导致任何连接,并且是来自单个的选择查询 table 。这就是为什么当您比较结果时,您会发现查询时间存在巨大差异。
有两种可能的解决方案:
<强>1。删除附加内容
删除附加项,每当您需要关系时使用 with
函数
<强>2。隐藏附加属性
您可以将此代码添加到您的Product
模型中:
protected $hidden = [
'created_at',
'deleted_at',
'updated_at',
'interests',
'brand',
'options',
'sizes',
'items',
'images',
'comment_count',
'discount',
'suits_me_count'
];
当您需要属性时,只需使用 $product->makeVisible('property_name')
。否则,默认情况下不会加载或查询这些属性
关于mysql - Eloquent 使用远程 MySQL DB 花费的时间太长,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48814659/