Sobes.tech
Middle+

Jak optimalizovat operátor ORDER BY RAND()?

sobes.tech AI

Odpověď od AI

Optimalizace ORDER BY RAND() je obtížná, protože vyžaduje úplný výběr dat pro generování náhodného čísla pro každý řádek. Typické přístupy:

  1. Výběr náhodného identifikátoru:

    • Získat počet řádků v tabulce.
    • Generovat náhodné číslo od 0 do N-1 (nebo 1 do N).
    • Vybrat řádek s odpovídajícím posunem nebo OFFSET.
    SELECT COUNT(*) FROM your_table;
    -- Předpokládá se, že celkový počet řádků = N
    
    SELECT * FROM your_table LIMIT 1 OFFSET floor(random() * N);
    

    Tento způsob je vhodný pro výběr jednoho nebo několika náhodných řádků. Není efektivní pro velké množství řádků.

  2. Náhodný výběr podle rozsahu id:

    • Najít minimální a maximální id.
    • Generovat náhodné číslo v tomto rozsahu.
    • Vybrat řádek s id >= náhodné_číslo pomocí LIMIT.
    SELECT MIN(id), MAX(id) FROM your_table;
    -- Předpokládá se, že získány min_id, max_id
    
    -- V aplikaci generujeme náhodné id v rozsahu [min_id, max_id]
    -- Napří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 přeskočit řádky, pokud jsou mezery v id.

  3. Vytvoření dočasné tabulky nebo použití poddotazu s řazením podle náhodného čísla:

    • Vybrat podmnožinu dat nebo pouze id v poddotazu.
    • Použít ORDER BY RAND() na toto 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;
    

    Snižuje zátěž, pokud je LIMIT použit na poddotazu.

  4. Použití doplňkového pole s náhodným číslem:

    • Přidat do tabulky pole pro uložení náhodného čísla.
    • Pravidelně aktualizovat toto pole pro všechny řádky.
    • Řadit podle tohoto pole.
    -- Přidání pole
    ALTER TABLE your_table ADD random_sort_key FLOAT;
    
    -- Pravidelná aktualizace
    UPDATE your_table SET random_sort_key = RAND();
    
    -- Výběr
    SELECT * FROM your_table ORDER BY random_sort_key LIMIT 10;
    

    Vyžaduje změny ve schématu a pozadí aktualizačního procesu.

  5. Algoritmus "zamíchání" (Fisher-Yates) mimo databázi:

    • Vybrat všechna id (nebo všechna data, pokud jsou malá).
    • Zamíchat seznam v aplikaci.
    • Vybrat prvních N prvků.
    // Předpokládá se, že ids je []int
    // ids = ... // Získání ids z databáze
    
    rand.Shuffle(len(ids), func(i, j int) {
        ids[i], ids[j] = ids[j], ids[i]
    })
    
    // Nyní jsou první N prvky ids náhodné
    // Můžete je použít pro výběr úplných řádků
    // SELECT * FROM your_table WHERE id IN (...)
    

    Vhodné pouze pro tabulky s malým počtem řádků.

Volba nejlepší metody závisí na velikosti tabulky, požadovaném počtu náhodných řádků a konkrétním systému správy databází. Pro většinu případů, kdy je potřeba vybrat několik náhodných řádků z velké tabulky, bude efektivnější kombinace získání id s následným OFFSET nebo WHERE id IN (...), než čisté ORDER BY RAND().