ORDER BY RAND()
je pomalý, protože DBMS musí číst všechny řádky, třídit je všechny, jen aby zachoval jen několik řádků. Výkon tohoto dotazu tedy silně závisí na počtu řádků v tabulce a se zvyšujícím se počtem řádků klesá.
Neexistuje způsob, jak to optimalizovat.
Existují však alternativy:
Můžete implementovat „získat 5 náhodných řádků“ provedením 6 dotazů:
- získáte počet řádků v tabulce (tento můžete uložit do mezipaměti)
-
proveďte 5 dotazů s
OFFSET <random offset from 0 to $number_of_rows-1> LIMIT 1
(tj. číst a vracet pouze jeden řádek z nějakého náhodného offsetu)Například:
SELECT * FROM Products OFFSET 42 LIMIT 1
(poznámka:prozatím bez připojení)Takové dotazy jsou velmi rychlé a běží v čase prakticky nezávislém na velikosti tabulky.
To by mělo být hodně rychlejší než ORDER BY RAND()
.
Nyní, abyste získali náhodný obrázek pro každý náhodný produkt:
SELECT *
FROM (
SELECT *
FROM Products
OFFSET 42 LIMIT 1
) p
JOIN ProductImages pi
ON pi.product_id = p.id
ORDER BY RAND()
LIMIT 1
Vnitřní dotaz je stále rychlý a vnější třídí pouze několik řádků (za předpokladu, že na produkt je málo obrázků), a tak může stále používat pořadí podle rand().