다음 튜토리얼 칼럼은 Laravel에서 소개할 예정입니다. ChunkById 방식을 사용할 때 정렬을 하지 마세요! , 도움이 필요한 친구들에게 도움이 되길 바랍니다!
chunkById 방식 사용 시 정렬을 하지 말아주세요
최근 개발 작업을 하다가 이상한 문제가 발생하여 공유드리고자 합니다
문제 설명
으로 인해 데이터를 일괄적으로 처리해야 하는데, 이 데이터의 양이 너무 많아서 한꺼번에 꺼내어 실행하는 것은 비현실적입니다. 다행히 라라벨에서는 편리하게 처리할 수 있도록 ChunkById 메소드를 제공하고 있습니다. 의사 코드는 다음과 같습니다
Student::query() ->where('is_delete', false) ->orderBy('id', 'DESC') ->chunkById(200, function($students) { // 在这里进行逻辑处理 });
언뜻 보면 문제가 없지만 실제로 코드를 실행해 보면 ChunkById가 처음에만 실행되고 두 번째 이후에는 어떤 이유로 실행이 중지되는 것을 알 수 있습니다. 시간.
원인 찾기
라라벨 소스코드의 ChunkById 코드는 다음과 같습니다
public function chunkById($count, callable $callback, $column = null, $alias = null) { $column = is_null($column) ? $this->getModel()->getKeyName() : $column; $alias = is_null($alias) ? $column : $alias; $lastId = null; do { $clone = clone $this; $results = $clone->forPageAfterId($count, $lastId, $column)->get(); $countResults = $results->count(); if ($countResults == 0) { break; } if ($callback($results) === false) { return false; } $lastId = $results->last()->{$alias}; unset($results); } while ($countResults == $count); return true; }
while 루프는 $countResults == $count를 기준으로 판단하므로 이 두 변수를 덤프합니다. 그리고 우리는 이 두 가지가 처음으로 일치할 때, 두 번째로 일치하지 않는 데이터로 인해 프로그램이 중지된다는 것을 알게 될 것입니다.
위 코드에서 $count는 $results = $clone->forPageAfterId($count, $lastId, $column)->get();에 의해 획득됩니다.
forPageAfterId 메소드를 계속해서 살펴보세요
public function forPageAfterId($perPage = 15, $lastId = 0, $column = 'id') { $this->orders = $this->removeExistingOrdersFor($column); if (! is_null($lastId)) { $this->where($column, '>', $lastId); } return $this->orderBy($column, 'asc') ->take($perPage); }
We 여기에서 반환된 결과는 orderBy에 따라 오름차순으로 정렬되는 반면 원래 코드는 내림차순으로 정렬되어 개수가 일관되지 않게 되어 ChunkById 실행이 종료되는 것을 볼 수 있습니다.
Solution
이전 orderBy('id', 'desc')를 제거하세요.
Student::query() ->where('is_delete', false) ->chunkById(200, function($students) { // 在这里进行逻辑处理 });
요약
앞으로는 ChunkById나 Chunk 메소드를 사용할 때 커스텀 정렬을 추가하지 마세요
배우면서 배우게 될 것입니다. . .
위 내용은 ChunkById 방식을 사용할 때 정렬을 하지 마세요!의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!