Я нашел метод chunk в документации, который помогает получить тысячи записей. Хотя до сих пор неясно, насколько эффективно получить родственные модели. Сейчас моя лучшая попытка:

Student::chunk(100, function ($students){
      foreach ($students as $student){
          $student->with(['campus','program','group'])->get();
      };
});

Это приводит меня к результату 1996ms; 2009 queries, 1996 of which are duplicated. Это в тестовой среде, где у меня 3500 строк в таблице students.

В env продукта будет больше 23k строк. Как улучшить запрос данных в случае отношения, если модель student имеет отношение belongsTo к таблицам campuses, programs и groups?

Student.php

public function campus()
{
    return $this->belongsTo(Campus::class);
}

public function program()
{
    return $this->belongsTo(Program::class);
}

public function group()
{
    return $this->belongsTo(Group::class);
}

И второй вопрос: как отправить эти данные на блейд? Я думаю, просто поместите его в переменную, а не в решение, потому что переменной может не хватить памяти .... или я ошибаюсь?

ОБНОВЛЕНИЕ: Подсказка @Pavel Lint значительно уменьшает количество запросов, но все же половина из них дублируется:

enter image description here

1
Virtual Device 25 Ноя 2019 в 18:19
Правильно ли вы проиндексировали базу данных? Кроме того, я всегда нахожу, что сырые запросы работают лучше, чем красноречивые. При необходимости используйте joins. Если вы этого не сделали, возможно, вам тоже стоит попробовать.
 – 
user3532758
25 Ноя 2019 в 18:30

3 ответа

При отправке в blade-сервер не забывайте (или вы можете это знать) Laravel имеет встроенные параметры разбивки на страницы.

Таким образом, вам не нужно использовать фрагмент, поскольку разбиение на страницы ограничивает размер запроса - и это имеет дополнительное преимущество, предоставляя функциональность пользовательского интерфейса разбиения на страницы (я предполагаю, что это то, что вам нужно, когда вы говорите «отправка на лезвие».

Разбиение на страницы в Laravel

Так что может быть что-то вроде этого:

$studsPerPage = 20; // or however many students you want to display at a time
$students = Student::with(['campus','program','group'])->paginate($studsPerPage);

А затем в пользовательском интерфейсе вашего лезвия:

<div class="container">
    @foreach ($students as $stud)
        {{ $stud->name }} And student details
    @endforeach
</div>

use this cool pagination tool to surf over pages of Studs
{{ $students->links() }}
0
ChronoFish 25 Ноя 2019 в 18:45

Установите Yajra Datatable Package для управления данными, он поможет вам. Yajra - это сторонний инструмент. он предоставляет вам разбиение на страницы, но разбиение на страницы уже включено в laravel, но есть еще одно преимущество, которое yajra предлагает вам, а также поиск в реальном времени с помощью ajax.

Для установки выполните команду:

композитору требуется yajra / laravel-datatables-oracle

После этого вам нужно установить провайдеров и псевдоним.

Конфиг / app.php

'провайдеры' => [ .... Yajra \ DataTables \ DataTablesServiceProvider :: класс, ]

'псевдонимы' => [ .... 'DataTables' => Yajra \ DataTables \ Facades \ DataTables :: class, ]

На этом шаге нам нужно создать маршрут для файла макета таблиц данных и еще один для получения данных. поэтому откройте файл routes / web.php и добавьте следующий маршрут.

Маршруты / web.php

Route :: get ('Student', ['uses' => 'StudentController @ index', 'as' => 'Students.index']);

Тогда студент-контроллер

  public function index(Request $request)
{
    if ($request->ajax()) {
        $data = Student::latest()->get();
        return Datatables::of($data)
                ->addIndexColumn()
                ->addColumn('action', function($row){

                       $btn = '<a href="javascript:void(0)" class="edit btn btn-primary btn-sm">View</a>';

                        return $btn;
                })
                ->rawColumns(['action'])
                ->make(true);
    }

    return view('Students');
}

На последнем шаге давайте создадим Students.blade.php (resources / views / Students.blade.php) для макета, и мы напишем здесь код дизайна и поместим следующий код:

Ресурсы / просмотры / Students.blade.php

<!DOCTYPE html>
<html>
<head>
    <title>Laravel </title>
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css" />
    <link href="https://cdn.datatables.net/1.10.16/css/jquery.dataTables.min.css" rel="stylesheet">
    <link href="https://cdn.datatables.net/1.10.19/css/dataTables.bootstrap4.min.css" rel="stylesheet">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.js"></script>  
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.0/jquery.validate.js"></script>
    <script src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
    <script src="https://cdn.datatables.net/1.10.19/js/dataTables.bootstrap4.min.js"></script>
</head>
<body>

<div class="container">
    <table class="table table-bordered data-table">
        <thead>
            <tr>
                <th>No</th>
                <th>Name</th>
                <th>Email</th>
                <th width="100px">Action</th>
            </tr>
        </thead>
        <tbody>
        </tbody>
    </table>
</div>

</body>

<script type="text/javascript">
  $(function () {

    var table = $('.data-table').DataTable({
        processing: true,
        serverSide: true,
        ajax: "{{ route('Students.index') }}",
        columns: [
            {data: 'DT_RowIndex', name: 'DT_RowIndex'},
            {data: 'name', name: 'name'},
            {data: 'email', name: 'email'},
            {data: 'action', name: 'action', orderable: false, searchable: false},
        ]
    });

  });
</script>
</html>

Тогда:

php artisan serve

Теперь откройте браузер и пройдите по своему маршруту

http: // localhost: 8000 / Students

0
Nadir 25 Ноя 2019 в 21:41

Думаю, вам будет лучше, если вы сделаете наоборот:

Student::with(['campus','program','group'])->chunk(100, function ($students){
    // your logic here
});

Чтобы отправить все данные в блейд, вы можете собрать их в одном массиве и отправить в представление.

2
Pavel Lint 25 Ноя 2019 в 18:28
Спасибо! 24 запроса, 10 из которых дублируются. Сейчас намного лучше, но все еще есть повторяющиеся запросы. Есть идеи, почему они появляются?
 – 
Virtual Device
25 Ноя 2019 в 18:43
Дублировал как? Могут ли они просто иметь другое СМЕЩЕНИЕ, потому что вы используете chunk?
 – 
Pavel Lint
25 Ноя 2019 в 18:49
Я использую Telescope для проверки дублирования
 – 
Virtual Device
25 Ноя 2019 в 19:02
Ну не могли бы вы поделиться дублированными запросами?
 – 
Pavel Lint
25 Ноя 2019 в 19:03
Скриншот прикреплен к основному посту. Пожалуйста, взгляните
 – 
Virtual Device
25 Ноя 2019 в 20:51