быстрый выбор случайной строки из большой таблицы в MySQL - PullRequest
44 голосов
/ 17 октября 2008

Какой быстрый способ выбрать случайную строку из большой таблицы MySQL?

Я работаю в php, но меня интересует любое решение, даже если оно на другом языке.

Ответы [ 24 ]

1 голос
/ 17 октября 2008

Простой, но медленный способ (хорошо для небольших таблиц)

SELECT * from TABLE order by RAND() LIMIT 1
1 голос
/ 17 октября 2008

В псевдокоде:

sql "select id from table"
store result in list
n = random(size of list)
sql "select * from table where id=" + list[n]

Предполагается, что id является уникальным (первичным) ключом.

0 голосов
/ 31 мая 2012

Я столкнулся с проблемой, когда мои идентификаторы не были последовательными. Что я придумал с этим.

SELECT * FROM products WHERE RAND()<=(5/(SELECT COUNT(*) FROM products)) LIMIT 1

Возвращенных строк примерно 5, но я ограничиваю их до 1.

Если вы хотите добавить еще одно предложение WHERE, оно станет немного интереснее. Скажем, вы хотите искать товары со скидкой.

SELECT * FROM products WHERE RAND()<=(100/(SELECT COUNT(*) FROM pt_products)) AND discount<.2 LIMIT 1

Что вам нужно сделать, это убедиться, что вы возвращаете достаточно результата, поэтому я установил его на 100. Наличие предложения WHERE discount <.2 в подзапросе было в 10 раз медленнее, поэтому лучше возвращать больше результатов и ограничивать . </p>

0 голосов
/ 12 марта 2016

Я использовал это, и работа была сделана ссылка от здесь

SELECT * FROM myTable WHERE RAND()<(SELECT ((30/COUNT(*))*10) FROM myTable) ORDER BY RAND() LIMIT 30;
0 голосов
/ 24 февраля 2015

Используйте запрос ниже, чтобы получить случайную строку

SELECT user_firstname ,
COUNT(DISTINCT usr_fk_id) cnt
FROM userdetails 
GROUP BY usr_fk_id 
ORDER BY cnt ASC  
LIMIT 1
0 голосов
/ 22 января 2014

SELECT DISTINCT * FROM yourTable WHERE 4 = 4 LIMIT 1;

0 голосов
/ 27 сентября 2008

Классический «SELECT id ИЗ таблицы ORDER BY RAND () LIMIT 1» на самом деле в порядке.

См. Следующую выдержку из руководства MySQL:

Если вы используете LIMIT row_count с ORDER BY, MySQL завершит сортировку, как только найдет первые строки row_count отсортированного результата, вместо сортировки всего результата.

0 голосов
/ 17 октября 2008

При заказе вы выполните полную проверку таблицы. Лучше всего, если вы выберете счетчик (*), а затем получите случайную строку = rownum между 0 и последним реестром

0 голосов
/ 22 февраля 2014

Я вижу здесь много решений. Один или два кажется нормальным, но другие решения имеют некоторые ограничения. Но следующее решение будет работать для всех ситуаций

select a.* from random_data a, (select max(id)*rand() randid  from random_data) b
     where a.id >= b.randid limit 1;

Здесь, id, не нужно быть последовательным. Это может быть любой столбец первичного ключа / уникального / автоинкремента. Пожалуйста, смотрите следующий Самый быстрый способ выбрать случайную строку из большой таблицы MySQL

Спасибо Зиллуру - www.techinfobest.com

0 голосов
/ 18 октября 2008

Быстрый и грязный метод:

SET @COUNTER=SELECT COUNT(*) FROM your_table;

SELECT PrimaryKey
FROM your_table
LIMIT 1 OFFSET (RAND() * @COUNTER);

Сложность первого запроса O (1) для таблиц MyISAM.

Второй запрос сопровождает полное сканирование таблицы. Сложность = O (n)

Грязный и быстрый метод:

Храните отдельную таблицу только для этой цели. Вы также должны вставлять те же строки в эту таблицу при вставке в исходную таблицу. Предположение: нет УДАЛЕНИЯ.

CREATE TABLE Aux(
  MyPK INT AUTO_INCREMENT,
  PrimaryKey INT
);

SET @MaxPK = (SELECT MAX(MyPK) FROM Aux);
SET @RandPK = CAST(RANDOM() * @MaxPK, INT)
SET @PrimaryKey = (SELECT PrimaryKey FROM Aux WHERE MyPK = @RandPK);

Если разрешено УДАЛЕНИЕ,

SET @delta = CAST(@RandPK/10, INT);

SET @PrimaryKey = (SELECT PrimaryKey
                   FROM Aux
                   WHERE MyPK BETWEEN @RandPK - @delta AND @RandPK + @delta
                   LIMIT 1);

Общая сложность O (1).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...