Optimierung von Laravel-Abfragen: Der richtige Weg, Daten aufzuteilen

王林
Freigeben: 2024-09-09 06:31:38
Original
781 Leute haben es durchsucht

Optimizing Laravel Queries: The Right Way to Chunk Data

Warum sollten Sie die Verwendung von Chunk vermeiden?

Es ist besser, chunkById anstelle von chunk zu verwenden, um fehlende Zeilen bei Batch-Updates zu vermeiden. Die Verwendung von Chunk kann den Offset nachfolgender Abfragen nach dem Aktualisieren von Zeilen verschieben, was dazu führt, dass unverarbeitete Zeilen übersprungen werden.

Zum Beispiel:

Post::where('processed', 0)->chunk(100, function($posts) {
    foreach($posts as $post) {
       $post->processed = 1;
       $post->save();
    }
});
Nach dem Login kopieren

Der obige Code generiert die folgenden Abfragen.

select * from `posts` where `processed` = 0 limit 100 offset 0
select * from `posts` where `processed` = 0 limit 100 offset 100
...
Nach dem Login kopieren

Der erste Block aktualisiert 100 Zeilen. Die zweite Abfrage überspringt, ohne sich dessen bewusst zu sein, 100 unverarbeitete Zeilen, da sie immer noch den Offset verwendet.

Das Obige wird ausführlich erklärt von
Thai Nguyen Hung

Wie kann ich eine begrenzte Anzahl von Zeilen aufteilen?

Wenn wir versuchen, eine begrenzte Anzahl von Zeilen mit der chunk()-Methode von Laravel zu verarbeiten, können wir davon ausgehen, dass der folgende Code nur 5 Benutzer in Stapeln von 2 verarbeitet:

$query  = \App\Models\User::query()->take(5);

$query->chunk(2, function ($users) {
  // Process users
});
Nach dem Login kopieren

Dadurch werden jedoch alle Benutzer in der Datenbank verarbeitet, jeweils zwei gleichzeitig. Dies geschieht, weil die chunk()-Methode von Laravel das auf die Abfrage angewendete take()-Limit ignoriert, was dazu führt, dass alle Zeilen in Blöcken verarbeitet werden.

Um sicherzustellen, dass nur eine begrenzte Anzahl von Zeilen (z. B. 5 Benutzer) in Blöcken verarbeitet werden, können wir einen benutzerdefinierten Indexzähler implementieren, der die Chunking-Schleife unterbricht, nachdem das angegebene Limit erreicht wurde. Der folgende Code erreicht dies:

class UserProcessor
{
    private int $index = 0;
    private int $limit = 5;

    public function process()
    {
        $query = \App\Models\User::query();

        $query->chunk(2, function ($users) {
            foreach ($users as $user) {
                $this->index++;

                // Process each user here
                // Example: $user->processData();

                if ($this->index >= $this->limit) {
                    // Stop processing after reaching the limit
                    return false;  // This will stop chunking
                }
            }
        });
    }
}
Nach dem Login kopieren

Hinweis

$index und $limit sind Eigenschaften der Klasse, keine Methodenvariablen, die mit use($index, $limit) an den Abschluss übergeben werden. Dies liegt daran, dass über use() übergebene Variablen nach Wert in das Abschlussobjekt kopiert werden. Daher wirken sich alle Änderungen innerhalb des Abschlusses nicht auf die ursprünglichen Werte aus, weshalb es sich um Klasseneigenschaften handeln muss, um Änderungen über Iterationen hinweg ordnungsgemäß zu aktualisieren und zu verfolgen.

Das obige ist der detaillierte Inhalt vonOptimierung von Laravel-Abfragen: Der richtige Weg, Daten aufzuteilen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:dev.to
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage