Поделитесь алгоритмом выборки из БД случайного набора записей (например 10 записей). Я всегда использовал: Код (Text): ORDER BY RAND() ... но я был очень удивлён, когда обнаружил, что этот метод работает медленно. Это незаметно на небольших таблицах, но попробуйте поэксперементировать с таблицей в миллион записей и вы заметите, что такая выборка занимает порядка 0.5 сек. На порталах с нормальной нагрузкой это очень много для одного запроса. Запрос выглядит так: Код (Text): SELECT `id` FROM `big_tab` ORDER BY RAND() LIMIT 10; Для создания таблицы в миллион записей можно использовать вот такой запрос: Код (Text): CREATE TABLE `big_tab` ( `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY (`id`) ) COLLATE='utf8_general_ci' ENGINE=MyISAM; INSERT INTO `big_tab` ( `id` ) VALUES ( NULL ); INSERT INTO `big_tab` ( `id` ) SELECT NULL FROM `big_tab`; INSERT INTO `big_tab` ( `id` ) SELECT NULL FROM `big_tab`; INSERT INTO `big_tab` ( `id` ) SELECT NULL FROM `big_tab`; INSERT INTO `big_tab` ( `id` ) SELECT NULL FROM `big_tab`; INSERT INTO `big_tab` ( `id` ) SELECT NULL FROM `big_tab`; INSERT INTO `big_tab` ( `id` ) SELECT NULL FROM `big_tab`; INSERT INTO `big_tab` ( `id` ) SELECT NULL FROM `big_tab`; INSERT INTO `big_tab` ( `id` ) SELECT NULL FROM `big_tab`; INSERT INTO `big_tab` ( `id` ) SELECT NULL FROM `big_tab`; INSERT INTO `big_tab` ( `id` ) SELECT NULL FROM `big_tab`; INSERT INTO `big_tab` ( `id` ) SELECT NULL FROM `big_tab`; INSERT INTO `big_tab` ( `id` ) SELECT NULL FROM `big_tab`; INSERT INTO `big_tab` ( `id` ) SELECT NULL FROM `big_tab`; INSERT INTO `big_tab` ( `id` ) SELECT NULL FROM `big_tab`; INSERT INTO `big_tab` ( `id` ) SELECT NULL FROM `big_tab`; INSERT INTO `big_tab` ( `id` ) SELECT NULL FROM `big_tab`; INSERT INTO `big_tab` ( `id` ) SELECT NULL FROM `big_tab`; INSERT INTO `big_tab` ( `id` ) SELECT NULL FROM `big_tab`; INSERT INTO `big_tab` ( `id` ) SELECT NULL FROM `big_tab`; INSERT INTO `big_tab` ( `id` ) SELECT NULL FROM `big_tab`;
igordata, если таблица на движке InnoDB то такой запрос занимает тоже порядка 0.5 сек (даже чуть больше чем для MyISAM). А Вы какой движок посоветуете?
Сейчас в тестовой таблице пропусков нет, но в рабочем варианте пропуски конечно будут (записи удаляются).
Можно попробовать генерить случайные двадцать айдишников, выбирать и смотреть хватило ли. Повторить если нет.
ищите ту на формуме. эту тему уже обсасывали вдоль и поперек. там было много решений, со своими плюсами и минусами.
тормоза ORDER BY RAND() объясняются тем, что при каждом запросе создается временная таблица с чем-то вроде "новых случайных id" для нашей сортируемой таблицы. хорошее решение для одной случайной записи из большой таблицы: http://jan.kneschke.de/projects/mysql/order-by-rand/ суть — выбор первого значения с id >= RAND() * MAX(id). скорость почти постоянна для любого размера таблицы. для N случайных записей можно добавить какие-то трюки с циклом, кешем и блекджеком.
artoodetoo, спасибо, это интересно. Значит придётся использовать процедуру в SQL, чтобы достать несколько ID'шников.
Мне оч нравится движок blackhole. А вообще надо ждать, пока Falcon не войдет в релизы, интересная штука намечается. Еще из экзотики движок Memory. Работает а-ля мемкеш, только реляционный. То есть таблички существуют не в виде файлов, а в виде куска оперативки. Работают соответственно. Для часто дергаемой мелкотуры, которую не жалко потерять - самое оно.
мемори жрёт новую память каждый раз когда ему не хватает, и жрёт ее столько, сколько уже имеет - растёт на двое. а освободившуюся не отдаёт. это надо понимать, прежде, чем использовать.
А разве на него не забили? Зависит от характера разреженности, например, если записи с id: 1,99,100, то случайность крайне условная. В такой ситуации нужен limit X,1 Пример реализации здесь: http://sqlinfo.ru/forum/viewtopic.php?pid=11053#p11053