Jak zoptymalizować operator ORDER BY RAND()?
sobes.tech AI
Odpowiedź od AI
Optymalizacja ORDER BY RAND() jest trudna, ponieważ wymaga pełnego pobrania danych do wygenerowania losowej liczby dla każdego wiersza. Typowe podejścia:
-
Wybór losowego identyfikatora:
- Uzyskaj liczbę wierszy w tabeli.
- Wygeneruj losową liczbę od 0 do N-1 (lub 1 do N).
- Wybierz wiersz z odpowiednim przesunięciem lub
OFFSET.
SELECT COUNT(*) FROM your_table; -- Zakłada się, że łączna liczba wierszy = N SELECT * FROM your_table LIMIT 1 OFFSET floor(random() * N);Ta metoda nadaje się do wyboru jednego lub kilku losowych wierszy. Nieefektywna dla dużej liczby wierszy.
-
Losowy wybór w zakresie
id:- Znajdź minimalny i maksymalny
id. - Wygeneruj losową liczbę w tym zakresie.
- Wybierz wiersz z
id >= losowa_liczba, używającLIMIT.
SELECT MIN(id), MAX(id) FROM your_table; -- Zakłada się, że uzyskano min_id, max_id -- W aplikacji wygeneruj losowe id w zakresie [min_id, max_id] -- Na przykład: losowe_id = min_id + floor(random() * (max_id - min_id + 1)) SELECT * FROM your_table WHERE id >= losowe_id LIMIT 1;Może pominąć wiersze, jeśli występują luki w
id. - Znajdź minimalny i maksymalny
-
Tworzenie tymczasowej tabeli lub użycie podzapytania z sortowaniem po losowej liczbie:
- Wybierz podzbiór danych lub tylko
idw podzapytaniu. - Zastosuj
ORDER BY RAND()do tego podzbioru.
SELECT * FROM your_table AS t1 JOIN (SELECT id FROM your_table ORDER BY RAND() LIMIT 100) AS t2 ON t1.id = t2.id;Zmniejsza obciążenie, jeśli
LIMITjest nałożony na podzapytanie. - Wybierz podzbiór danych lub tylko
-
Użycie dodatkowego pola z losową liczbą:
- Dodaj do tabeli pole do przechowywania losowej liczby.
- Okresowo aktualizuj to pole dla wszystkich wierszy.
- Sortuj po tym polu.
-- Dodanie pola ALTER TABLE your_table ADD random_sort_key FLOAT; -- Okresowa aktualizacja UPDATE your_table SET random_sort_key = RAND(); -- Wybór SELECT * FROM your_table ORDER BY random_sort_key LIMIT 10;Wymaga zmian w schemacie i procesu aktualizacji w tle.
-
Algorytm "tasowania" (Fisher-Yates) poza bazą danych:
- Wybierz wszystkie
id(lub wszystkie dane, jeśli są małe). - Tasuj listę w aplikacji.
- Wybierz pierwsze N elementów.
// Zakłada się, że ids to []int // ids = ... // Pobierz ids z bazy danych rand.Shuffle(len(ids), func(i, j int) { ids[i], ids[j] = ids[j], ids[i] }) // Teraz pierwsze N elementów ids jest losowe // Możesz użyć ich do wyboru pełnych wierszy // SELECT * FROM your_table WHERE id IN (...)Nadaje się tylko dla tabel z niewielką liczbą wierszy.
- Wybierz wszystkie
Wybór optymalnej metody zależy od rozmiaru tabeli, wymaganego liczby losowych wierszy i konkretnego systemu zarządzania bazą danych. W większości przypadków, gdy trzeba wybrać niewielką liczbę losowych wierszy z dużej tabeli, bardziej wydajne będzie pobranie id i następnie użycie OFFSET lub WHERE id IN (...), niż bezpośrednie sortowanie po RAND().