CREATE TABLE `a` (
`id` int(8) unsigned NOT NULL AUTO_INCREMENT,
`md5` char(32) NOT NULL
PRIMARY KEY (`id`)
)
INSERT INTO `a` (`id`) VALUES (null),(null),(null),(null)... 163712 ;)
UPDATE `a` SET md5 = MD5(`id`);
SELECT * FROM `a` ORDER BY RAND() LIMIT 10; -> (10 rows, Query took 0.3345 sec)
SELECT * FROM `a` ORDER BY RAND() LIMIT 10; -> (10 rows, Query took 0.2538 sec)
SELECT * FROM `a` ORDER BY RAND() LIMIT 10; -> (10 rows, Query took 0.2299 sec)
ALTER TABLE `a` ADD `f` SMALLINT(3) UNSIGNED NOT NULL, ADD INDEX (`f`);
UPDATE `a` SET `f` = RAND()*1000;
The number 1000 is the main accelerating factor. To them, I reduce the table in which an ordinary ORDER BY RAND will pass 1000 times. With a table of 163712 rows, you should get about 164 rows per f. Checking:SELECT COUNT(1) FROM `a` WHERE `f` = 123; -> 169
SELECT * FROM `a` WHERE `f` = 231 ORDER BY RAND() LIMIT 10; -> (10 rows, Query took 0.0801 sec)
SELECT * FROM `a` WHERE `f` = 231 ORDER BY RAND() LIMIT 10; -> (10 rows, Query took 0.0017 sec)
Aha, the second time turned out a re-sorted sample from the mysql cache. If the repetition of the results is not very scary, then such a more nimble result will fit, but it is better to change the number f with each query.SELECT * FROM `a` WHERE `f` = 396 ORDER BY RAND() LIMIT 10; -> (10 rows, Query took 0.0147 sec)
SELECT * FROM `a` WHERE `f` = 753 ORDER BY RAND() LIMIT 10; -> (10 rows, Query took 0.0020 sec)
SELECT * FROM `a` WHERE `f` = 189 ORDER BY RAND() LIMIT 10; -> (10 rows, Query took 0.0019 sec)
SELECT * FROM `a` WHERE `f` = 945 ORDER BY RAND() LIMIT 10; -> (10 rows, Query took 0.0235 sec)
SELECT * FROM `a` WHERE `f` IN (100,500) ORDER BY RAND() LIMIT 10;
ALTER TABLE `a` ADD `feed` TINYINT(1) UNSIGNED NOT NULL, ADD INDEX (`feed`);
UPDATE `a` SET feed = RAND()*9;
And now, actually, feint ears:(SELECT * FROM `a` WHERE `f` = 283 AND `feed` = 0 ORDER BY RAND() LIMIT 10)
UNION (SELECT * FROM `a` WHERE `f` = 283 AND `feed` = 1 ORDER BY RAND() LIMIT 10)
UNION (SELECT * FROM `a` WHERE `f` = 283 AND `feed` = 2 ORDER BY RAND() LIMIT 10)
UNION (SELECT * FROM `a` WHERE `f` = 283 AND `feed` = 3 ORDER BY RAND() LIMIT 10)
UNION (SELECT * FROM `a` WHERE `f` = 283 AND `feed` = 4 ORDER BY RAND() LIMIT 10)
UNION (SELECT * FROM `a` WHERE `f` = 283 AND `feed` = 5 ORDER BY RAND() LIMIT 10)
UNION (SELECT * FROM `a` WHERE `f` = 283 AND `feed` = 6 ORDER BY RAND() LIMIT 10)
UNION (SELECT * FROM `a` WHERE `f` = 283 AND `feed` = 7 ORDER BY RAND() LIMIT 10)
UNION (SELECT * FROM `a` WHERE `f` = 283 AND `feed` = 8 ORDER BY RAND() LIMIT 10)
UNION (SELECT * FROM `a` WHERE `f` = 283 AND `feed` = 9 ORDER BY RAND() LIMIT 10)
ORDER BY feed; -> (97 rows, Query took 0.7973 sec)
f -> (99 rows, Query took 0.0093 sec)
f -> (98 rows, Query took 0.0197 sec)
Here it is desirable to choose more than 10 rows for fidelity;) and filter the extra for PHP.SET @rnd = RAND(); SELECT * FROM `a` WHERE `f` = @rnd ORDER BY RAND() LIMIT 10;
Source: https://habr.com/ru/post/55864/
All Articles