用远程MySQL DB来说太久了

mig*_*glz 8 mysql rest amazon-web-services laravel eloquent

我正在开发一个Web(Laravel)和iOS应用程序,它们都使用我正在使用Laravel开发的REST API.来自AWS RDS实例托管的MySQL数据库的API查询.

当我同时设置本地主机上的API和应用程序,以及配置为连接本地数据库的API(与应用程序和API相同的机器)时,它可以正常工作,但问题是当我设置API来查询时AWS RDS数据库而不是本地.简单的查询用eloquent,如

Product::where('brand_id', '=', $id)
               ->get()
Run Code Online (Sandbox Code Playgroud)

需要10到15分钟才能完成,但如果我使用查询构建器执行相同的查询,则为expample;

DB::select('select * from products where brand_id = ?', [$id]);
Run Code Online (Sandbox Code Playgroud)

工作良好.

直接在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
Run Code Online (Sandbox Code Playgroud)

我的产品型号:

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');
    }

}
Run Code Online (Sandbox Code Playgroud)

而我的品牌型号:

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();
    }


}
Run Code Online (Sandbox Code Playgroud)

Par*_*ras 5

问题是你的Product模型中的这段代码:

protected $appends = [
    'interests',
    'brand',
    'options',
    'sizes',
    'items',
    'images',
    'comment_count',
    'discount',
    'suits_me_count'
];
Run Code Online (Sandbox Code Playgroud)

这些属性是关系,因此每次Eloquent读取/返回行时它们都会导致多个连接.

此查询:DB::select('select * from products where brand_id = ?', [$id]);不会导致任何联接,并且是来自单个表的选择查询.这就是为什么当你比较结果时,你发现查询时间有很大的不同.

有两种可能的解决方案:

1.删​​除附加内容

删除附加内容,只要您需要关系,请使用该with功能

2.隐藏附加属性

您可以将此代码添加到您的Product模型中:

protected $hidden = [
    'created_at',
    'deleted_at',
    'updated_at',
    'interests',
    'brand',
    'options',
    'sizes',
    'items',
    'images',
    'comment_count',
    'discount',
    'suits_me_count'
];
Run Code Online (Sandbox Code Playgroud)

当你需要一个房产时才使用$product->makeVisible('property_name').否则,默认情况下,不会加载或查询这些属性

  • 不确定,可能有很多原因.也许brand_id 25具体没有任何关系,也许它没有很多产品.我不认为测试是苹果对苹果.无论情况如何,代码几乎都表明正在加载这些关系,从而导致多个连接,所以我很确定这是真正的原因 (2认同)