Sobes.tech
Middle+

Ako optimalizovať operátor ORDER BY RAND()?

sobes.tech AI

Odpoveď od AI

Optimalizácia ORDER BY RAND() je ťažká, pretože vyžaduje úplný výber dát na generovanie náhodného čísla pre každý riadok. Typické prístupy:

  1. Výber náhodného identifikátora:

    • Získať počet riadkov v tabuľke.
    • Generovať náhodné číslo od 0 do N-1 (alebo 1 do N).
    • Vybrať riadok s vhodným posunom alebo OFFSET.
    SELECT COUNT(*) FROM your_table;
    -- Predpokladá sa, že celkový počet riadkov = N
    
    SELECT * FROM your_table LIMIT 1 OFFSET floor(random() * N);
    

    Tento spôsob je vhodný na výber jedného alebo niekoľkých náhodných riadkov. Nie je efektívny pre veľké množstvo riadkov.

  2. Náhodný výber podľa rozsahu id:

    • Nájsť minimálne a maximálne id.
    • Generovať náhodné číslo v tomto rozsahu.
    • Vybrať riadok s id >= náhodné_číslo pomocou LIMIT.
    SELECT MIN(id), MAX(id) FROM your_table;
    -- Predpokladá sa, že boli získané min_id, max_id
    
    -- V aplikácii generujeme náhodné id v rozsahu [min_id, max_id]
    -- Napríklad: náhodné_id = min_id + floor(random() * (max_id - min_id + 1))
    
    SELECT * FROM your_table WHERE id >= náhodné_id LIMIT 1;
    

    Môže preskočiť riadky, ak sú medzery v id.

  3. Vytvorenie dočasnej tabuľky alebo použitie poddotazu s zoradením podľa náhodného čísla:

    • Vybrať podmnožinu dát alebo len id v poddotaze.
    • Použiť ORDER BY RAND() na túto podmnožinu.
    SELECT *
    FROM your_table AS t1 JOIN (SELECT id FROM your_table ORDER BY RAND() LIMIT 100) AS t2
    ON t1.id = t2.id;
    

    Znižuje záťaž, ak je LIMIT uplatnený na poddotaze.

  4. Použitie doplnkového poľa s náhodným číslom:

    • Pridať do tabuľky pole na uloženie náhodného čísla.
    • Pravidelne aktualizovať toto pole pre všetky riadky.
    • Zoradiť podľa tohto poľa.
    -- Pridanie poľa
    ALTER TABLE your_table ADD random_sort_key FLOAT;
    
    -- Pravidelná aktualizácia
    UPDATE your_table SET random_sort_key = RAND();
    
    -- Výber
    SELECT * FROM your_table ORDER BY random_sort_key LIMIT 10;
    

    Vyžaduje zmeny v schéme a pozadí aktualizačného procesu.

  5. Algoritmus "zamiešania" (Fisher-Yates) mimo databázy:

    • Vybrať všetky id (alebo všetky dáta, ak sú malé).
    • Zamiešať zoznam v aplikácii.
    • Vybrať prvých N prvkov.
    // Predpokladá sa, že ids je []int
    // ids = ... // Získanie ids z databázy
    
    rand.Shuffle(len(ids), func(i, j int) {
        ids[i], ids[j] = ids[j], ids[i]
    })
    
    // Teraz prvých N prvkov ids sú náhodné
    // Môžete ich použiť na výber úplných riadkov
    // SELECT * FROM your_table WHERE id IN (...)
    

    Vhodné iba pre tabuľky s malým počtom riadkov.

Výber najlepšej metódy závisí od veľkosti tabuľky, požadovaného počtu náhodných riadkov a konkrétneho systému správy databáz. Pre väčšinu prípadov, keď je potrebné vybrať niekoľko náhodných riadkov z veľkej tabuľky, bude efektívnejšie kombinácia získania id s následným OFFSET alebo WHERE id IN (...), než čistý ORDER BY RAND().