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:
-
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ů.
-
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é_číslopomocí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. - Najít minimální a maximální
-
Vytvoření dočasné tabulky nebo použití poddotazu s řazením podle náhodného čísla:
- Vybrat podmnožinu dat nebo pouze
idv 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
LIMITpoužit na poddotazu. - Vybrat podmnožinu dat nebo pouze
-
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.
-
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ů.
- Vybrat všechna
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().