Auth:: user() → имя пользователя и т.д. Очень медленные
У меня жуткая проблема. Приложение Laravel 5 очень медленное, для полной загрузки требуется 1-3 секунды, это то, что недопустимо.
После нескольких часов отладки я обнаружил, что проблема - Auth::user()
, более конкретно, когда вы пытаетесь получить доступ к чему-то вроде Auth::user()->username
.
Что я заметил: 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 Service Provider и, следовательно, 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
Любая идея, почему это происходит?
Спасибо!
Ответы
Ответ 1
Используйте xdebug для создания профиля выполнения. Затем загрузите этот файл и откройте его в Wincachegrind или Kcachegrind (в зависимости от того, какая ОС вы используете на рабочем столе).
В этих программах вы можете развернуть и посмотреть, что требуется дополнительное время, дважды щелкнув и посмотрев на столбцы, чтобы узнать, сколько времени что-то предприняло.
Ответ 2
Используйте технологию кеширования, если у вас есть большая проблема с данными и производительностью, связанная с этим, например, таблица memcache!
Ответ 3
Фасад Auth возвращает объект класса Illuminate\Auth\Guard, обычно он кэширует весь объект, который вы запрашиваете.
Может ли быть, что где-то в вашем приложении фасад был перезаписан расширенным до версии, которая только кэширует идентификатор, а не все свойства?
Возможно, вы захотите сделать внутренний запрос для пользователя в User::with('personalData','banned')
в своей исходной нагрузке, чтобы он отобразил все ваши соответствующие данные.
В основном убедитесь, что все ваши поля загружены в первый запрос для пользователя.
Очень странно, что загружается только идентификатор пользователя, как будто ваш пользовательский объект получает экземпляр с идентификатором, но не выполняет запрос до его запроса.
Ответ 4
Использовать метод вместо Facade.
Use:
auth()->user()->username.
Avoid use of:
Auth::user()->username.