DB Query внутри foreach l oop делает мое приложение медленным - PullRequest
0 голосов
/ 06 марта 2020

Код ниже используется для отображения таблицы с 15 результатами на странице. Для этого я использую две разные базы данных, одна - база данных WordPress, другая - личная база данных, которую я создал.

Первый запрос используется для получения значений таблицы из базы данных WordPress, но это не так. не получить имя пользователя, так как WordPress хранит только идентификатор пользователя в этой таблице. Единственное место, где у меня есть правильное имя пользователя, находится в моей второй личной базе данных.

Для этого я использовал foreach l oop, чтобы заменить идентификаторы для имен пользователей. Итак, внутри l oop есть новый запрос, используемый для получения имен пользователей.

Моя проблема в том, что при каждой загрузке страницы я выполняю 16 запросов к БД одновременно поэтому он делает 16 запросов к базе данных, и это замедляет мою страницу.

public function index() {

    $posts = DB::connection('mysql2')
        ->table('wp_rocketsciencebrposts')
        ->select('ID', 'post_title', 'post_status', 'post_author', 'post_date')
        ->whereIn('post_status', ['publish', 'private'])
        ->where('post_type', 'post')
        ->orderBy('id', 'desc')
        ->paginate(15, ['*'], 'posts');

    $posts = compact('posts');

    foreach($posts['posts'] as &$value){

        //this DB Query is making my page slow, since it's inside this foreach loop, therefore, making 16 database requests
        $value->post_author = DB::connection('mysql')
            ->table('users')
            ->select('name')
            ->where('rsbwordpressid', $value->post_author)
            ->value('name');

    }

    return view('posts/posts', $posts);

}

Я уверен, что решение очень простое, но я не могу придумать стратегию о том, как поместить второй запрос к БД за пределами l oop, избегая всех ненужных запросов к базе данных.

Pls, help.

Ответы [ 3 ]

1 голос
/ 06 марта 2020

Так что вы можете столкнуться с некоторыми странностями, используя Laravel и Wordpress. Я могу дать вам несколько советов от Laravel POV о том, как вы могли бы сделать это лучше.


Красноречивые модели

Если вы еще этого не сделали, сделать две модели (Post & User) и установить отношения между ними.

Пользователь. php

class User extends Model
{
    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'wp_rocketsciencebrposts';

    public function posts()
    {
        return $this->hasMany(Post::class, 'post_author', 'name');
    }
}

Сообщение. php

class User extends Model
{
    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'users';

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

Контроллеры

Внутри вашего контроллера вы должны теперь иметь возможность делать что-то вроде этого

$post = Post::with('user')
            ->whereIn('post_status', ['publish', 'private'])
            ->where('post_type', 'post')
            ->orderBy('id', 'desc')
            ->paginate(15, ['*'], 'posts');

Теперь каждый из ваших Post объектов в $posts должен иметь ->user загрузка загружена.

Теперь вы можете go $post->user->name, чтобы получить имя автора поста

0 голосов
/ 09 марта 2020

Вот ответ, который я ожидал увидеть:

public function index() {

    $posts = DB::connection('mysql2')
    ->table('wp_rocketsciencebrposts')
    ->select('ID', 'post_title', 'post_status', 'post_author', 'post_date')
    ->whereIn('post_status', ['publish', 'private'])
    ->where('post_type', 'post')
    ->orderBy('id', 'desc')
    ->paginate(15, ['*'], 'posts');

    $user_ids = $posts->pluck('post_author')->toArray();

    $users = DB::connection('mysql')
    ->table('users')
    ->whereIn('rsbwordpressid', $user_ids)
    ->pluck('rsbwordpressid', 'name')
    ->toArray();

    $posts = compact('posts');

    $users = array_flip($users);

    foreach($posts['posts'] as $value) {

        $value->post_author = $users[$value->post_author];

    }

    return view('posts/posts', $posts)->with('mensagemSucesso', print_r($users) );

}
0 голосов
/ 06 марта 2020

Вы должны использовать один запрос с объединением:

$posts = DB::connection('mysql2')
    ->table('wp_rocketsciencebrposts')
    ->join('users', 'users.rsbwordpressid', '=', 'wp_rocketsciencebrposts.post_author')
    ->select('ID', 'post_title', 'post_status', 'post_author', 'post_date', 'users.name')
    ->whereIn('post_status', ['publish', 'private'])
    ->where('post_type', 'post')
    ->orderBy('id', 'desc')
    ->paginate(15, ['*'], 'posts');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...