Я хотел бы знать, в чем разница между чанком laravel и методом курсора laravel. Какой метод больше подходит для использования? Какие будут варианты использования для них обоих? Я знаю, что вы должны использовать курсор для экономии памяти, но как это на самом деле работает в бэкэнде?
Подробное объяснение с примером было бы полезно, потому что я искал на stackoverflow и других сайтах, но я не нашел много информации.
Вот фрагмент кода из документации laravel.
Результаты Chunking
Flight::chunk(200, function ($flights) {
foreach ($flights as $flight) {
//
}
});
Использование курсоров
foreach (Flight::where('foo', 'bar')->cursor() as $flight) {
//
}
На самом деле, этот вопрос может привлечь какой-то самоуверенный ответ, однако простой ответ здесь Laravel Docs
Просто для справки:
Это кусок:
Это курсор:
Chunk извлекает записи из базы данных и загружает их в память, устанавливая курсор на последнюю извлеченную запись, чтобы избежать конфликта.
Таким образом, преимущество здесь, если вы хотите переформатировать большой запись перед отправкой, или вы хотите выполнить операцию с n-м числом записей за раз, тогда это полезно. Например, если вы создаете лист вида out / excel, то вы можете считать записи в счетчиках до тех пор, пока они не будут выполнены, чтобы все они не были загружены в память одновременно и, таким образом, достигли предела памяти.
Курсор использует генераторы PHP, вы можете проверить php генераторы Однако на странице есть интересная подпись:
Хотя я не могу гарантировать, что я полностью понимаю концепцию Cursor, но для Chunk, chunk выполняет запрос с каждым размером записи, извлекает его и передает его в замыкание для дальнейшей работы с записями.
Надеюсь, это полезно.
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`
Но драйвер не получает набор результатов сразу.
У нас есть сравнение: 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 |
+--------------+------------+------------+
Я сделал несколько тестов, используя курсор и где
foreach (\App\Models\Category::where('type','child')->get() as $res){
}
foreach (\App\Models\Category::where('type', 'child')->cursor() as $flight) {
//
}
return view('welcome');