我遇到了一个令人讨厌的问题。我的Laravel 5应用程序非常慢,完全加载需要1-3秒,这是不容忍的。
经过数小时的调试后,我发现问题是Auth::user()
,更具体地说,当您尝试访问Auth::user()->username
之类的内容时。{/ p>
我注意到:Auth::user()->id
速度极快,Auth::user()->username
需要1-3秒。它也似乎没有与mySQL服务器有什么东西,因为正在执行完全相同的查询,无论我使用->id
还是->username
。
使用->username
时不仅速度慢,而且->id
以外的所有内容似乎都很慢,而且在访问Auth::user()->roles
等角色时也是如此。
如果重要,我使用Entrust进行权限/角色管理。
用户模型:
<?php namespace App\Models;
use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Zizaco\Entrust\Traits\EntrustUserTrait;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
class User extends Model implements AuthenticatableContract, CanResetPasswordContract
{
use Authenticatable, CanResetPassword, EntrustUserTrait, SoftDeletes;
protected $table = 'users';
protected $guarded = ['id'];
protected $fillable = ['username', 'email', 'activation_code'];
protected $hidden = ['password', 'remember_token'];
protected $dates = ['deleted_at'];
public function personalData()
{
return $this->hasOne(UserPersonalData::class);
}
public function banned()
{
return $this->hasOne(BanUser::class);
}
}
即使我删除了Entrust服务提供商,也因此删除了EntrustUserTrait,它仍然像以前一样慢。
SHOW CREATE TABLE users
根据要求
CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`email` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`password` varchar(60) COLLATE utf8_unicode_ci NOT NULL,
`activated` tinyint(1) NOT NULL DEFAULT '0',
`activation_code` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`remember_token` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`deleted_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `users_username_unique` (`username`),
UNIQUE KEY `users_email_unique` (`email`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
知道为什么会这样吗?
谢谢!
答案 0 :(得分:3)
使用xdebug生成执行的配置文件。然后下载该文件并在Wincachegrind或Kcachegrind中打开它(取决于您在桌面上运行的操作系统)
在这些程序中,您可以向下钻取并查看通过双击并查看列来节省额外时间的内容,以查看已花费的时间。
答案 1 :(得分:0)
如果您有大量数据和性能问题,请使用缓存技术,例如 memcache 表格!
答案 2 :(得分:0)
Auth facade返回类Illuminate \ Auth \ Guard的对象,通常它会缓存您请求的整个对象。
可能是你的应用程序中的某个地方已被覆盖扩展到只缓存id而不是所有属性的版本?
您可能希望在初始加载中将用户的初始查询转换为User::with('personalData','banned')
,以便获取所有相关数据。
基本上确保在用户的第一个查询中急切加载所有字段。
非常奇怪的是只加载了用户ID,就好像你的用户对象用id实例化了,但是在你提出请求之前它不会执行查询。
答案 3 :(得分:0)
使用方法代替Facade。
Use:
auth()->user()->username.
Avoid use of:
Auth::user()->username.