Kako optimizovati operator ORDER BY RAND()?
sobes.tech АИ
Одговор од АИ
Оптимизација ORDER BY RAND() је тешка, јер захтева потпуно преузимање података за генерисање случајног броја за сваки ред. Типични приступи:
-
Избор случајног идентификатора:
- Добити број редова у таблици.
- Генерисати случајни број од 0 до N-1 (или 1 до N).
- Изабрати ред са одговарајућим помером или
OFFSET.
SELECT COUNT(*) FROM your_table; -- Предпоставља се да је укупни број редова = N SELECT * FROM your_table LIMIT 1 OFFSET floor(random() * N);Ова метода је погодна за избор једног или малог броја случајних редова. Неефикасна је за велики број редова.
-
Случајни избор по опсегу
id:- Пронаћи минимални и максимални
id. - Генерисати случајни број у том опсегу.
- Изабрати ред са
id >= случајни_бројкористећиLIMIT.
SELECT MIN(id), MAX(id) FROM your_table; -- Предпоставља се да су добијени min_id, max_id -- У апликацији генеришемо случајни id у опсегу [min_id, max_id] -- На пример: случајни_id = min_id + floor(random() * (max_id - min_id + 1)) SELECT * FROM your_table WHERE id >= случајни_ид LIMIT 1;Може пропустити редове ако постоје празни простори у
id. - Пронаћи минимални и максимални
-
Креирање привремене табеле или коришћење подзадатка са сортирањем по случајном броју:
- Изабрати подскуп података или само
idу подзадатку. - Примени
ORDER BY RAND()на овај подскуп.
SELECT * FROM your_table AS t1 JOIN (SELECT id FROM your_table ORDER BY RAND() LIMIT 100) AS t2 ON t1.id = t2.id;Смањује оптерећење ако је
LIMITнаметнут на подзадатку. - Изабрати подскуп података или само
-
Користење додатног поља са случајним бројем:
- Додати поље у табелу за чување случајног броја.
- Периодично ажурирати ово поље за све редове.
- Сортирати по овом пољу.
-- Додавање поља ALTER TABLE your_table ADD random_sort_key FLOAT; -- Периодично ажурирање UPDATE your_table SET random_sort_key = RAND(); -- Избор SELECT * FROM your_table ORDER BY random_sort_key LIMIT 10;Захтева измене у шеми и позадински процес ажурирања.
-
Алгоритам "мешања" (Fisher-Yates) ван базе података:
- Изабрати сва
id(или све податке ако су мали). - Мешати листу у апликацији.
- Изабрати првих N елемената.
// Предпоставља се да је ids []int // ids = ... // Добијање ids из базе података rand.Shuffle(len(ids), func(i, j int) { ids[i], ids[j] = ids[j], ids[i] }) // Сада су првих N елемената ids случајни // Могу се користити за избор пуних редова // SELECT * FROM your_table WHERE id IN (...)Погодно само за табеле са малим бројем редова.
- Изабрати сва
Избор најбоље методе зависи од величине табеле, захтеваног броја случајних редова и конкретног система управљања базама података. За већину случајева, када је потребно изабрати мали број случајних редова из велике табеле, комбинација добијања id са накнадним OFFSET или WHERE id IN (...) ће бити ефикаснија од чистог ORDER BY RAND().