AKTUALIZACJA 2016
To rozwiązanie działa najlepiej przy użyciu indeksowanej kolumny .
Oto prosty przykład zoptymalizowanej ławki zapytań oznaczonej 100 000 wierszy.
ZOPTYMALIZOWANE:300 ms
SELECT
g.*
FROM
table g
JOIN
(SELECT
id
FROM
table
WHERE
RAND() < (SELECT
((4 / COUNT(*)) * 10)
FROM
table)
ORDER BY RAND()
LIMIT 4) AS z ON z.id= g.id
uwaga na temat limitu :limit 4 i 4/liczba(*). Czwórki muszą być tą samą liczbą. Zmiana liczby zwracanych nie wpływa tak bardzo na prędkość. Benchmark na limicie 4 i limicie 1000 są takie same. Limit 10 000 zajął do 600 ms
uwaga o dołączeniu :Losowanie samego identyfikatora jest szybsze niż losowanie całego wiersza. Ponieważ musi skopiować cały wiersz do pamięci, należy go losowo. Połączeniem może być dowolna tabela, która jest połączona z podzapytaniem, aby zapobiec skanowaniu tabel.
zanotuj, gdzie klauzula :gdzie liczba ogranicza ilość wyników, które są losowane. Pobiera procent wyników i sortuje je, a nie całą tabelę.
zanotuj zapytanie podrzędne :Warunek klauzuli if wykonującej sprzężenia i dodatkowe where należy umieścić zarówno w podzapytaniu, jak i w podzapytaniu. Aby uzyskać dokładną liczbę i przywrócić prawidłowe dane.
NIEOPTYMALIZOWANE:1200 ms
SELECT
g.*
FROM
table g
ORDER BY RAND()
LIMIT 4
ZALETY
4x szybciej niż order by rand()
. To rozwiązanie może działać z każdą tabelą z indeksowaną kolumną.
MINY
Jest to trochę skomplikowane ze złożonymi zapytaniami. Konieczność utrzymania 2 baz kodu w podzapytaniach