Подтвердить что ты не робот

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

Любая идея, почему это происходит?

Спасибо!

4b9b3361

Ответ 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.