Versuchen Sie Folgendes:
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
Dies ist besonders effizient auf MyISAM
(da der COUNT(*)
ist sofort), aber sogar in InnoDB
es ist 10
mal effizienter als ORDER BY RAND()
.
Die Hauptidee dabei ist, dass wir nicht sortieren, sondern stattdessen zwei Variablen behalten und die running probability
berechnen einer Zeile, die im aktuellen Schritt ausgewählt werden soll.
Weitere Einzelheiten finden Sie in diesem Artikel in meinem Blog:
Aktualisierung:
Wenn Sie nur einen einzigen zufälligen Datensatz auswählen müssen, versuchen Sie Folgendes:
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
)
)
Dies setzt Ihre ac_id
voraus 's werden mehr oder weniger gleichmäßig verteilt.