В чем разница между курсором Laravel и методом фрагмента Laravel?

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

Подробное объяснение с примером было бы полезно, потому что я искал на stackoverflow и других сайтах, но я не нашел много информации.

Вот фрагмент кода из документации laravel.

Результаты Chunking

Flight::chunk(200, function ($flights) {
foreach ($flights as $flight) {
//
}
});

Использование курсоров

foreach (Flight::where('foo', 'bar')->cursor() as $flight) {
//
}

9

Решение

На самом деле, этот вопрос может привлечь какой-то самоуверенный ответ, однако простой ответ здесь Laravel Docs

Просто для справки:

Это кусок:

введите описание изображения здесь

Это курсор:

введите описание изображения здесь

Chunk извлекает записи из базы данных и загружает их в память, устанавливая курсор на последнюю извлеченную запись, чтобы избежать конфликта.

Таким образом, преимущество здесь, если вы хотите переформатировать большой запись перед отправкой, или вы хотите выполнить операцию с n-м числом записей за раз, тогда это полезно. Например, если вы создаете лист вида out / excel, то вы можете считать записи в счетчиках до тех пор, пока они не будут выполнены, чтобы все они не были загружены в память одновременно и, таким образом, достигли предела памяти.

Курсор использует генераторы PHP, вы можете проверить php генераторы Однако на странице есть интересная подпись:

введите описание изображения здесь

Хотя я не могу гарантировать, что я полностью понимаю концепцию Cursor, но для Chunk, chunk выполняет запрос с каждым размером записи, извлекает его и передает его в замыкание для дальнейшей работы с записями.

Надеюсь, это полезно.

13

Другие решения

chunk основан на нумерации страниц, он поддерживает номер страницы и выполняет циклы за вас.

Например, DB::table('users')->select('*')->chunk(100, function($e) {}) будет делать несколько запросов, пока набор результатов не станет меньше размера чанка (100):

select * from `users` limit 100 offset 0;
select * from `users` limit 100 offset 100;
select * from `users` limit 100 offset 200;
select * from `users` limit 100 offset 300;
select * from `users` limit 100 offset 400;
...

cursor основывается на PDOStatement::fetch и генератор.

$cursor = DB::table('users')->select('*')->cursor()
foreach ($cursor as $e) { }

выдаст один запрос:

select * from `users`

Но драйвер не получает набор результатов сразу.

6

У нас есть сравнение: chunk () против курсора ()

  • курсор (): высокая скорость
  • chunk (): постоянное использование памяти

10000 записей:

+-------------+-----------+------------+
|             | Time(sec) | Memory(MB) |
+-------------+-----------+------------+
| get()       |      0.17 |         22 |
| chunk(100)  |      0.38 |         10 |
| chunk(1000) |      0.17 |         12 |
| cursor()    |      0.16 |         14 |
+-------------+-----------+------------+

100 000 записей:

+--------------+------------+------------+
|              | Time(sec)  | Memory(MB) |
+--------------+------------+------------+
| get()        |        0.8 |     132    |
| chunk(100)   |       19.9 |      10    |
| chunk(1000)  |        2.3 |      12    |
| chunk(10000) |        1.1 |      34    |
| cursor()     |        0.5 |      45    |
+--------------+------------+------------+
  • TestData: таблица пользователей миграции по умолчанию Laravel
  • Усадьба 0.5.0
  • PHP 7.0.12
  • MySQL 5.7.16
  • Laravel 5.3.22
4

Я сделал несколько тестов, используя курсор и где

foreach (\App\Models\Category::where('type','child')->get() as $res){

}

foreach (\App\Models\Category::where('type', 'child')->cursor() as $flight) {
//
}

return view('welcome');

вот результат:
кусок быстрее, спасибо, используя где

0
По вопросам рекламы [email protected]