Sobes.tech
Middle+

Kuidas optimeerida operaatorit ORDER BY RAND()

sobes.tech AI

Vastus AI-lt

Optimizēt ORDER BY RAND() ir grūti, jo tas prasa pilnu datu atlasi, lai ģenerētu nejaušu skaitli katrai rindai. Biežākie pieejas veidi:

  1. Nejauša identifikatora izvēle:

    • Iegūt rindu skaitu tabulā.
    • Ģenerēt nejaušu skaitli no 0 līdz N-1 (vai 1 līdz N).
    • Izvēlēties rindu ar atbilstošo nobīdi vai OFFSET.
    SELECT COUNT(*) FROM your_table;
    -- Pieņemot, ka kopējais rindu skaits = N
    
    SELECT * FROM your_table LIMIT 1 OFFSET floor(random() * N);
    

    Šī pieeja ir piemērota vienas vai nelielas nejaušu rindu izvēlei. Nav efektīva lielam rindas skaitam.

  2. Nejauša izvēle pēc id diapazona:

    • Atrod minimālo un maksimālo id.
    • Ģenerēt nejaušu skaitli šajā diapazonā.
    • Izvēlēties rindu ar id >= nejaušais_skaitlis, izmantojot LIMIT.
    SELECT MIN(id), MAX(id) FROM your_table;
    -- Pieņemot, ka iegūti min_id, max_id
    
    -- Pielietojumā ģenerē nejaušu id diapazonā [min_id, max_id]
    -- Piemēram: nejaušais_id = min_id + floor(random() * (max_id - min_id + 1))
    
    SELECT * FROM your_table WHERE id >= nejaušais_id LIMIT 1;
    

    Var izlaist rindas, ja ir tukšumi id vērtībās.

  3. Izveidot pagaidu tabulu vai izmantot apakšvaicājumu ar nejaušu kārtotāju:

    • Izvēlēties apakškopu vai tikai id ar apakšvaicājumu.
    • Pielietot ORDER BY RAND() šai apakškopai.
    SELECT *
    FROM your_table AS t1 JOIN (SELECT id FROM your_table ORDER BY RAND() LIMIT 100) AS t2
    ON t1.id = t2.id;
    

    Samazina slodzi, ja LIMIT ir uzlikts uz apakšvaicājumu.

  4. Papildu lauka ar nejaušu skaitli izmantošana:

    • Pievienot tabulai lauku nejaušā skaitļa glabāšanai.
    • Periodiski atjaunināt šo lauku visām rindām.
    • Kārtot pēc šī lauka.
    -- Lauka pievienošana
    ALTER TABLE your_table ADD random_sort_key FLOAT;
    
    -- Periodisks atjauninājums
    UPDATE your_table SET random_sort_key = RAND();
    
    -- Izvēle
    SELECT * FROM your_table ORDER BY random_sort_key LIMIT 10;
    

    Prasa izmaiņas shēmā un fonu procesu atjaunināšanai.

  5. "Maisīšanas" algoritma (Fisher-Yates) ārpus datu bāzes:

    • Izvēlēties visus id (vai visus datus, ja tie ir nelieli).
    • Maisīt sarakstu lietotnē.
    • Izvēlēties pirmos N elementus.
    // Pieņemot, ka ids ir []int
    // ids = ... // Iegūšana no datu bāzes
    
    rand.Shuffle(len(ids), func(i, j int) {
        ids[i], ids[j] = ids[j], ids[i]
    })
    
    // Tagad pirmie N elementi ir nejauši
    // Var izmantot tos, lai izvēlētos pilnas rindas
    // SELECT * FROM your_table WHERE id IN (...)
    

    Der tikai nelielām tabulām.

Izvēle optimālās metodes ir atkarīga no tabulas lieluma, nepieciešamā nejaušo rindu skaita un konkrētās DBMS. Parasti, ja nepieciešams izvēlēties nelielu skaitu nejaušu rindu no lielas tabulas, efektīvāk ir izmantot id iegūšanu ar turpmāko OFFSET vai WHERE id IN (...), nevis pilnu ORDER BY RAND().