Probeer dit:
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
Dit is vooral efficiënt op MyISAM
(sinds de COUNT(*)
is direct), maar zelfs in InnoDB
het is 10
keer efficiënter dan ORDER BY RAND()
.
Het belangrijkste idee hier is dat we niet sorteren, maar in plaats daarvan twee variabelen behouden en de running probability
berekenen. van een rij die moet worden geselecteerd in de huidige stap.
Zie dit artikel in mijn blog voor meer details:
Bijwerken:
Als u slechts één willekeurig record hoeft te selecteren, probeer dan dit:
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
)
)
Hierbij wordt ervan uitgegaan dat uw ac_id
's worden min of meer gelijkmatig verdeeld.