繁体   English   中英

如何优化Laravel雄辩的查询设计和关系?

[英]How to optimize Laravel Eloquent query design and relationships?

我一直在尝试学习更多有关如何更好地优化口才查询的方法。 我了解这涉及进行更可靠的数据库设计,并以“正确”的方式从服务器询问数据。

应用程序

我有一个示例应用程序,可让您添加任务列表,删除任务列表并进行编辑(大多数情况下只是标题)。 使用每个任务列表,您可以添加任务,删除任务和编辑任务。 典型的CRUD应用。

在此处输入图片说明

编码

除非有要求,否则我不会发布Vue组件,因为我不确定它是否相关。 我对初始查询优化更感兴趣。 我的关系设置如下:

型号: User.php

<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

use App\Models\TaskList;
use App\Task;

class User extends Authenticatable
{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'first', 'last', 'email', 'phone', 'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    public function lists() {
        return $this->hasMany(TaskList::class,'user_id');
    }
}

型号: TaskList.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

use User;
use App\Models\Task;

class TaskList extends Model
{
    protected $fillable = ['user_id','status','title'];

    public function user() {
        return $this->belongsTo(User::class);
    }

    public function tasks() {
        return $this->hasMany(Task::class,'list_id');
    }

    public function scopeLists() {
        return $this->where('user_id',auth()->user()->id);
    }
}

型号: Task.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

use App\Models\TaskList;
use App\User;

class Task extends Model
{
    public function list() {
        return $this->belongsTo(TaskList::class);
    }
}

控制器: TaskListController.php @index

public function index()
{
    $user = auth()->user()->load('lists.tasks');

    $data = [
        'lists' => $user->lists,
    ];        

    return view('user.tasklist',$data);
}

我认为我没有做任何特别的事情。 只是将我的数据粘贴到我的Vues数组成员lists

let app = new Vue({
        el: '#app',
        data: {
            lists: []
        }
    });

    @if(isset($lists))
        @foreach($lists as $list)
            app.lists.push({
                id: '{{ $list->id }}',
                title: '{!! addslashes($list->title) !!}',
                status: '{{ $list->status }}',
                tasks: JSON.parse('{!! $list->tasks !!}')
            });
        @endforeach
    @endif

问题

问题很简单,我的加载时间约为1秒。 我在网上阅读过混合信息,其中Laravel是一个缓慢的框架,其他人则声称它们可以获得20ms以下的加载时间,依此类推。 当然,我知道我处于开发环境中,并且我将从生产中看到不同的结果。 我也了解我有一些开发软件包,这些软件包不一定会在生产环境中加载,并且可以改善启动。 但是我认为下面的这些数字相当缓慢,这里还有其他情况。

在此处输入图片说明

在此处输入图片说明

问题

简而言之,在这种情况下如何改善性能并优化应用程序?

我想知道在这种特定情况下可以采取哪些步骤来提高应用程序性能。 在我的开发箱中,已满载所有开发包,我可以达到500毫秒以下的加载时间。 甚至500ms似乎也很慢。 可以达到200毫秒以下或100毫秒以下吗? 仅仅是硬件吗? 还是我对我的人际关系和负担完全错误?

"require": {
    "php": ">=7.1.3",
    "fideloper/proxy": "~4.0",
    "laravel/framework": "5.6.*",
    "laravel/tinker": "~1.0"
},
"require-dev": {
    "barryvdh/laravel-debugbar": "^3.1",
    "filp/whoops": "~2.0",
    "fzaninotto/faker": "~1.4",
    "mockery/mockery": "~1.0",
    "phpunit/phpunit": "~7.0",
    "symfony/thanks": "^1.0"
},

非常感谢您对此进行优化的见解!

关于您的代码

据我所知,您正在以正确的方式查询数据库,使用的是懒惰的eager loading ,它执行与eager load完全相同的查询。

您的数据库可能有问题。 您没有发布迁移。 你必须有外键task_lists.user_idtasks.list_id引用到user.idtask_lists.id分别。

其他可能的原因

  • 您说的是整个请求花费1s ,并且专注于查询,但是您没有在Laravel Debugbar上显示实际查询时间。
  • 请注意:引导时间为〜600ms,执行时间为〜300ms。 您的查询在执行时间内(还有很多其他事情)。
  • 引导时间主要受常见的坏蛋HDD导致的文件系统访问缓慢的影响。 替换为SSD,您会发现有很大的改进。
  • Laravel在运行Laravel Debugbar的调试模式下比在生产模式下慢得多。 这是因为启用了数据库查询记录器以及其他原因。
  • 如果您安装了php xdebug,它也会减慢执行时间
  • 在生产中从Laravel删除所有您不使用的东西。 不使用Cookie? 为什么要加载CookieServiceProvider 不使用文件系统? 为什么要加载FilesystemServiceProvider 查看您的app.providers配置。 因为您将加载较少的文件,所以这将减少启动时间。

好的,修复所有这些问题之后,如何提高性能?

假设您的环境进行了优化,代码优化,你仍然有缓慢的响应时间,它的时间来简介你的代码。 使用正确的探查器工具,您将确切看到正在减慢的代码段。

如果数据库查询本身很慢,并且您无能为力,您可以使用带有memcached或redis驱动程序的Laravel缓存 ,并缓存掉慢速查询,因此它们将在数据库中查询而不是结果内存,并以微秒为单位。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM