>PHP 프레임워크 >Laravel >ChunkById 방식을 사용할 때 정렬을 하지 마세요!

ChunkById 방식을 사용할 때 정렬을 하지 마세요!

藏色散人
藏色散人앞으로
2020-11-04 14:25:403832검색

다음 튜토리얼 칼럼은 Laravel에서 소개할 예정입니다. ChunkById 방식을 사용할 때 정렬을 하지 마세요! , 도움이 필요한 친구들에게 도움이 되길 바랍니다!

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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 learnku.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제