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

Jak mohu optimalizovat funkci ORDER BY RAND() MySQL?

Zkuste toto:

SELECT  *
FROM    (
        SELECT  @cnt := COUNT(*) + 1,
                @lim := 10
        FROM    t_random
        ) vars
STRAIGHT_JOIN
        (
        SELECT  r.*,
                @lim := @lim - 1
        FROM    t_random r
        WHERE   (@cnt := @cnt - 1)
                AND RAND(20090301) < @lim / @cnt
        ) i

To je zvláště efektivní na MyISAM (od COUNT(*) je okamžitý), ale dokonce i v InnoDB je to 10 krát efektivnější než ORDER BY RAND() .

Hlavní myšlenkou je, že netřídíme, ale místo toho si ponecháme dvě proměnné a vypočítáme running probability řádku, který má být vybrán v aktuálním kroku.

Další podrobnosti najdete v tomto článku na mém blogu:

Aktualizace:

Pokud potřebujete vybrat pouze jeden náhodný záznam, zkuste toto:

SELECT  aco.*
FROM    (
        SELECT  minid + FLOOR((maxid - minid) * RAND()) AS randid
        FROM    (
                SELECT  MAX(ac_id) AS maxid, MIN(ac_id) AS minid
                FROM    accomodation
                ) q
        ) q2
JOIN    accomodation aco
ON      aco.ac_id =
        COALESCE
        (
        (
        SELECT  accomodation.ac_id
        FROM    accomodation
        WHERE   ac_id > randid
                AND ac_status != 'draft'
                AND ac_images != 'b:0;'
                AND NOT EXISTS
                (
                SELECT  NULL
                FROM    accomodation_category
                WHERE   acat_id = ac_category
                        AND acat_slug = 'vendeglatohely'
                )
        ORDER BY
                ac_id
        LIMIT   1
        ),
        (
        SELECT  accomodation.ac_id
        FROM    accomodation
        WHERE   ac_status != 'draft'
                AND ac_images != 'b:0;'
                AND NOT EXISTS
                (
                SELECT  NULL
                FROM    accomodation_category
                WHERE   acat_id = ac_category
                        AND acat_slug = 'vendeglatohely'
                )
        ORDER BY
                ac_id
        LIMIT   1
        )
        )

To předpokládá vaše ac_id 's jsou distribuovány víceméně rovnoměrně.



  1. Jak načíst soubor JAR v databázi Oracle?

  2. Jak formátovat čísla se znaménkem mínus/plus v Oracle

  3. Oracle 11g získá všechny odpovídající výskyty regulárním výrazem

  4. Sql:rozdíl mezi dvěma daty