Sobes.tech
Middle+

Wie kann man den Operator ORDER BY RAND() optimieren?

sobes.tech KI

Antwort von AI

Die Optimierung von ORDER BY RAND() ist schwierig, da sie eine vollständige Datenabfrage erfordert, um für jede Zeile eine Zufallszahl zu generieren. Typische Ansätze:

  1. Auswahl einer zufälligen ID:

    • Anzahl der Zeilen in der Tabelle ermitteln.
    • Zufallszahl zwischen 0 und N-1 (oder 1 bis N) generieren.
    • Zeile mit entsprechendem Offset oder OFFSET auswählen.
    SELECT COUNT(*) FROM your_table;
    -- Es wird angenommen, dass die Gesamtzahl der Zeilen = N ist
    
    SELECT * FROM your_table LIMIT 1 OFFSET floor(random() * N);
    

    Diese Methode eignet sich für die Auswahl einer oder weniger zufälliger Zeilen. Für große Datenmengen ist sie ineffizient.

  2. Zufällige Auswahl anhand eines ID-Bereichs:

    • Minimal- und Maximal-ID ermitteln.
    • Zufallszahl in diesem Bereich generieren.
    • Zeile mit id >= zufallszahl auswählen, mit LIMIT.
    SELECT MIN(id), MAX(id) FROM your_table;
    -- Es wird angenommen, dass min_id, max_id ermittelt wurden
    
    -- In der Anwendung eine zufällige ID im Bereich [min_id, max_id] generieren
    -- Zum Beispiel: zufalls_id = min_id + floor(random() * (max_id - min_id + 1))
    
    SELECT * FROM your_table WHERE id >= zufalls_id LIMIT 1;
    

    Es können Zeilen übersprungen werden, wenn Lücken in id bestehen.

  3. Erstellen einer temporären Tabelle oder Verwendung einer Unterabfrage mit Sortierung nach Zufallszahl:

    • Teilmenge der Daten oder nur id in einer Unterabfrage auswählen.
    • ORDER BY RAND() auf diese Teilmenge anwenden.
    SELECT *
    FROM your_table AS t1 JOIN (SELECT id FROM your_table ORDER BY RAND() LIMIT 100) AS t2
    ON t1.id = t2.id;
    

    Reduziert die Last, wenn LIMIT auf die Unterabfrage angewendet wird.

  4. Verwendung eines zusätzlichen Feldes mit Zufallszahlen:

    • Ein Feld in der Tabelle hinzufügen, um eine Zufallszahl zu speichern.
    • Dieses Feld regelmäßig für alle Zeilen aktualisieren.
    • Nach diesem Feld sortieren.
    -- Feld hinzufügen
    ALTER TABLE your_table ADD random_sort_key FLOAT;
    
    -- Periodisches Update
    UPDATE your_table SET random_sort_key = RAND();
    
    -- Abfrage
    SELECT * FROM your_table ORDER BY random_sort_key LIMIT 10;
    

    Erfordert Änderungen am Schema und im Hintergrundaktualisierungsprozess.

  5. Fisher-Yates-Algorithmus außerhalb der Datenbank:

    • Alle IDs (oder alle Daten, wenn klein) auswählen.
    • Liste in der Anwendung mischen.
    • Die ersten N Elemente auswählen.
    // Es wird angenommen, dass ids []int ist
    // ids = ... // IDs aus der Datenbank holen
    
    rand.Shuffle(len(ids), func(i, j int) {
        ids[i], ids[j] = ids[j], ids[i]
    })
    
    // Die ersten N Elemente von ids sind jetzt zufällig
    // Sie können verwendet werden, um vollständige Zeilen auszuwählen
    // SELECT * FROM your_table WHERE id IN (...)
    

    Nur geeignet für Tabellen mit wenigen Zeilen.

Die optimale Methode hängt von der Tabellenlänge, der benötigten Anzahl an zufälligen Zeilen und dem verwendeten Datenbanksystem ab. Für die meisten Fälle, in denen eine kleine Anzahl zufälliger Zeilen aus einer großen Tabelle benötigt wird, ist die Kombination aus ID-Ermittlung und anschließendem OFFSET oder WHERE id IN (...) effizienter als reines ORDER BY RAND().