SELECT @min := MIN(id),
@max := MAX(id)
FROM tbl;
SELECT ... FROM tbl
WHERE id = FLOOR(@min + (@max - @min + 1) * RAND());
(Of course, you might be able to optimize this.
For example, @min is likely to be 1.)
SELECT @min := MIN(id),
@max := MAX(id)
FROM tbl;
SELECT ...
FROM tbl a
JOIN (
( SELECT id
FROM tbl
WHERE id = FLOOR(@min + (@max - @min + 1 - 50) * RAND())
ORDER BY id
LIMIT 50
) ORDER BY RAND()
LIMIT 10
) r ON a.id = r.id
ALTER TABLE tbl
ADD COLUMN rnd FLOAT NOT NULL
ADD INDEX(rnd);
UPDATE tbl SET rnd = RAND();
In subsequents INSERTs, set the `rnd` to RAND().
To fetch n random rows:
SELECT ... FROM tbl
WHERE rnd >= RAND()
ORDER BY rnd
LIMIT n;
ALTER TABLE tbl
ADD COLUMN rnd FLOAT NOT NULL
ADD INDEX(rnd);
UPDATE tbl SET rnd = RAND();
In subsequents INSERTs, set the `rnd` to RAND().
To fetch n random rows:
SELECT ...
FROM tbl a
JOIN (
( SELECT rnd
FROM tbl
WHERE rnd = @min + (@max - @min + 1 - 50) * RAND()
ORDER BY rnd
LIMIT 50
) ORDER BY RAND()
LIMIT 10
) r ON a.rnd = r.rnd
LIMIT 10
SELECT ...
FROM tbl a
JOIN (
( SELECT digest
FROM tbl
WHERE digest > MD5(RAND()))
ORDER BY digest
LIMIT 50
) ORDER BY RAND()
LIMIT 10
) r ON a.id = r.id
CREATE TABLE IF NOT EXISTS NewRandom (
rid INT UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMIARY KEY(rid, other_id)
)
SELECT id AS other_id FROM tbl ORDER BY RAND(); -- slow, but 'background'
# Note: That table will have 2 columns
DROP TABLE IF EXISTS OldRandom;
RENAME TABLE Random TO OldRandom, NewRandom TO Random; -- atomic and instantaneous
Fetch 10 random rows:
SELECT @max := MAX(rid) FROM Random;
SELECT ... FROM tbl t
JOIN Random r ON r.other_id = t.id
WHERE rid > (@max - 10 + 1) * RAND()
ORDER BY rid
LIMIT 10;