sql >> Databáze >  >> RDS >> Mysql

Optimalizace pomalého dotazu ORDER BY RAND().

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().




  1. Zkontrolujte, zda existuje přidružení, aniž by došlo k zásahu do databáze

  2. Distribuováno ve více sloupcích

  3. Alternativní řešení DCount a DLookup s MS SQL Server Backend

  4. Indexování tabulek na PostgreSQL pro výkon