Sobes.tech
Middle+

Hogyan lehet optimalizálni az ORDER BY RAND() operátort?

sobes.tech MI

Válasz az MI-től

Az ORDER BY RAND() optimalizálása nehéz, mivel minden sorhoz véletlenszám generálásához teljes adatkiválasztás szükséges. A tipikus megközelítések:

  1. Véletlenszerű azonosító kiválasztása:

    • A sorok számának lekérdezése.
    • Véletlenszám generálása 0-tól N-1-ig (vagy 1-től N-ig).
    • A megfelelő eltolással vagy OFFSET-tel kiválasztani a sort.
    SELECT COUNT(*) FROM your_table;
    -- Feltételezzük, hogy a total_rows = N
    
    SELECT * FROM your_table LIMIT 1 OFFSET floor(random() * N);
    

    Ez a módszer alkalmas egy vagy néhány véletlenszerű sor kiválasztására. Nem hatékony nagy adatmennyiség esetén.

  2. Véletlenszerű kiválasztás az id tartományában:

    • A minimális és maximális id megtalálása.
    • Véletlenszám generálása ebben a tartományban.
    • A id >= véletlenszám sor kiválasztása LIMIT-tel.
    SELECT MIN(id), MAX(id) FROM your_table;
    -- Feltételezzük, hogy min_id, max_id meg vannak határozva
    
    -- Az alkalmazásban generálunk véletlen `id`-t a [min_id, max_id] tartományban
    -- Például: véletlen_id = min_id + floor(random() * (max_id - min_id + 1))
    
    SELECT * FROM your_table WHERE id >= véletlen_id LIMIT 1;
    

    Előfordulhat, hogy kihagy sorokat, ha vannak üres id-k.

  3. Átmeneti táblázat vagy al-lekérdezés használata véletlenszerű rendezéssel:

    • Kiválasztani egy részhalmazt vagy csak az id-ket egy al-lekérdezésben.
    • Rendezi ezt a részhalmazt ORDER BY RAND()-tel.
    SELECT *
    FROM your_table AS t1 JOIN (SELECT id FROM your_table ORDER BY RAND() LIMIT 100) AS t2
    ON t1.id = t2.id;
    

    Csökkenti a terhelést, ha a LIMIT az al-lekérdezésre vonatkozik.

  4. További véletlenszám tároló mező használata:

    • Egy új mező hozzáadása a táblához a véletlenszám tárolására.
    • Rendszeres frissítés ennek a mezőnek az értékével.
    • Rendezés e szerint a mező szerint.
    -- Mező hozzáadása
    ALTER TABLE your_table ADD random_sort_key FLOAT;
    
    -- Rendszeres frissítés
    UPDATE your_table SET random_sort_key = RAND();
    
    -- Kiválasztás
    SELECT * FROM your_table ORDER BY random_sort_key LIMIT 10;
    

    Módosításokat igényel a séma és a háttérfrissítési folyamat.

  5. "Fisher-Yates" keverési algoritmus külső alkalmazásban:

    • Minden id (vagy minden adat, ha kicsi) kiválasztása.
    • A lista keverése az alkalmazásban.
    • Az első N elem kiválasztása.
    // Feltételezzük, hogy az ids []int típusú
    // ids = ... // Az id-k lekérése az adatbázisból
    
    rand.Shuffle(len(ids), func(i, j int) {
        ids[i], ids[j] = ids[j], ids[i]
    })
    
    // Most az első N elem véletlenszerű
    // Ezeket használhatjuk a teljes sorok kiválasztására
    // SELECT * FROM your_table WHERE id IN (...)
    

    Csak kis sorozatszámú táblákhoz alkalmas.

A legjobb módszer kiválasztása a táblázat méretétől, a kívánt véletlenszerű sorok számától és az adott adatbázis-kezelőtől függ. A legtöbb esetben, amikor néhány véletlenszerű sort kell kiválasztani egy nagy táblából, a id lekérése és az azt követő OFFSET vagy WHERE id IN (...) kombináció hatékonyabb, mint a tiszta ORDER BY RAND().