быстрый выбор случайной строки от большой таблицы в mysql

Исключение нулевого указателя генерируется, когда приложение пытается использовать null в случае, когда требуется объект. К ним относятся:

  1. Вызов метода экземпляра объекта null.
  2. Доступ или изменение поля объекта null.
  3. Принимая длину null, как если бы это был массив.
  4. Доступ или изменение слотов null, как если бы это был массив.
  5. Бросок null как будто это было значение Throwable.

Приложения должны бросать экземпляры этого класса, чтобы указать на другие незаконные использования объекта null.

Ссылка: http://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html

45
задан caitriona 4 October 2012 в 15:35
поделиться

16 ответов

Захватите весь идентификатор, выберите случайный от него и получите всю строку.

, Если Вы знаете, идентификатор последователен без дыр, можно просто захватить макс. и вычислить случайный идентификатор.

, Если существуют дыры тут и там, но главным образом последовательные значения, и Вы не заботитесь о немного скошенной случайности, захватываете макс. значение, вычисляете идентификатор и выбираете первую строку с идентификатором, равным или выше того, который Вы вычислили. Причина скоса состоит в том, что идентификатор после таких дыр будет иметь более высокий шанс того, чтобы быть выбранным, чем, которые следуют другому идентификатору.

, Если Вы заказываете случайным, Вы собираетесь иметь ужасное сканирование таблицы на руках, и Word , быстрый , не относится к такому решению.

не делают этого, и при этом Вы не должны заказывать GUID, он имеет ту же проблему.

48
ответ дан angry person 26 November 2019 в 20:53
поделиться

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

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).

-1
ответ дан fthiella 26 November 2019 в 20:53
поделиться

Я немного плохо знаком с SQL, но как насчет того, чтобы генерировать случайное число в PHP и использовать

SELECT * FROM the_table WHERE primary_key >= $randNr

это не решает проблему с дырами в таблице.

, Но вот скручивание на lassevks предложении:

SELECT primary_key FROM the_table

Использование mysql_num_rows () в PHP создают случайное число на основе вышеупомянутого результата:

SELECT * FROM the_table WHERE primary_key = rand_number

На стороне отмечают, насколько медленный SELECT * FROM the_table:
Создание случайного числа на основе mysql_num_rows() и затем перемещение указателя данных на ту точку mysql_data_seek(). Насколько медленный это будет на больших таблицах с, говорит миллион строк?

0
ответ дан LPL 26 November 2019 в 20:53
поделиться

Смотрите на эта ссылка Jan Kneschke или это, ТАК ответьте , поскольку они оба обсуждают тот же вопрос. ТАКИМ ОБРАЗОМ, ответ пробегается через различные варианты также и имеет некоторые хорошие предложения в зависимости от Ваших потребностей. Jan пробегается через все различные варианты и рабочие характеристики каждого. Он заканчивает со следующим для наиболее оптимизированного метода, которым можно сделать это в выборе MySQL:

SELECT name
  FROM random AS r1 JOIN
       (SELECT (RAND() *
                     (SELECT MAX(id)
                        FROM random)) AS id)
        AS r2
 WHERE r1.id >= r2.id
 ORDER BY r1.id ASC
 LIMIT 1;

HTH,

-Dipin

0
ответ дан Community 26 November 2019 в 20:53
поделиться

Классический "ИЗБРАННЫЙ идентификационный РЭНД ORDER BY таблицы FROM () ОГРАНИЧИВАЕТ 1", на самом деле в порядке.

См. следовать выборку из руководства MySQL:

при использовании ПРЕДЕЛА row_count с ORDER BY MySQL заканчивает сортировку, как только это нашло первые row_count строки отсортированного результата, вместо того, чтобы сортировать весь результат.

0
ответ дан igelkott 26 November 2019 в 20:53
поделиться

С порядком эй сделает таблицу полного сканирования. Его лучшее, если Вы проводите избранный подсчет (*) и позже получаете случайный row=rownum между 0 и последний реестр

0
ответ дан MazarD 26 November 2019 в 20:53
поделиться

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

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

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

1
ответ дан Anders Sandvig 26 November 2019 в 20:53
поделиться

Легкий, но медленный путь был бы (хорош для небольших таблиц)

SELECT * from TABLE order by RAND() LIMIT 1
1
ответ дан Vinko Vrsalovic 26 November 2019 в 20:53
поделиться

Добавьте столбец, содержащий расчетное случайное значение к каждой строке и использование это в пункте упорядочивания, ограничив одним результатом после выбора. Это разрабатывает быстрее, чем наличие сканирования таблицы это ORDER BY RANDOM() причины.

Обновление: все еще необходимо вычислить некоторое случайное значение до издания SELECT оператор после извлечения, конечно, например,

SELECT * FROM `foo` WHERE `foo_rand` >= {some random value} LIMIT 1
3
ответ дан Rob 26 November 2019 в 20:53
поделиться

Возможно, Вы могли сделать что-то как:

SELECT * FROM table 
  WHERE id=
    (FLOOR(RAND() * 
           (SELECT COUNT(*) FROM table)
          )
    );

Это предполагает, что Ваши Идентификационные номера все последовательны без разрывов.

3
ответ дан davr 26 November 2019 в 20:53
поделиться

Вот решение, которое работает справедливо быстро, и это получает лучшее случайное распределение без в зависимости от значений идентификаторов, являющихся непрерывным или запускающихся по телефону 1.

SET @r := (SELECT ROUND(RAND() * (SELECT COUNT(*) FROM mytable)));
SET @sql := CONCAT('SELECT * FROM mytable LIMIT ', @r, ', 1');
PREPARE stmt1 FROM @sql;
EXECUTE stmt1;
12
ответ дан Bill Karwin 26 November 2019 в 20:53
поделиться

MediaWiki использует интересный прием (для функции Special:Random Википедии): таблица со статьями имеет дополнительный столбец со случайным числом (сгенерированный, когда статья создается). Для получения случайной статьи генерируйте случайное число и получите статью со следующим большим, или меньшее (не вспоминайте, который), оценивают в столбце случайного числа. С индексом это может быть очень быстро. (И MediaWiki записан в PHP и разработан для MySQL.)

Этот подход может вызвать проблему, если получающиеся числа плохо распределяются; IIRC, это было закреплено на MediaWiki, поэтому если Вы решаете сделать это этот способ, которым необходимо смотреть на код, чтобы видеть, как это в настоящее время делало (вероятно, они периодически повторно создают столбец случайного числа).

30
ответ дан CesarB 26 November 2019 в 20:53
поделиться

Я знал, что должен был быть способ сделать это в едином запросе быстрым способом. И здесь это:

А быстрый путь без участия внешнего кода, благодарности

http://jan.kneschke.de/projects/mysql/order-by-rand/

SELECT name
  FROM random AS r1 JOIN
       (SELECT (RAND() *
                     (SELECT MAX(id)
                        FROM random)) AS id)
        AS r2
 WHERE r1.id >= r2.id
 ORDER BY r1.id ASC
 LIMIT 1;
37
ответ дан Vinko Vrsalovic 26 November 2019 в 20:53
поделиться

Для выбора нескольких случайных строк из данной таблицы (например, «слова») ) наша команда придумала такую ​​красоту:

SELECT * FROM
`words` AS r1 JOIN 
(SELECT  MAX(`WordID`) as wid_c FROM `words`) as tmp1
WHERE r1.WordID >= (SELECT (RAND() * tmp1.wid_c) AS id) LIMIT n
1
ответ дан 26 November 2019 в 20:53
поделиться

Есть еще один способ создания случайных строк, используя только запрос и без порядка с помощью rand (). Он включает в себя пользовательские переменные. См. , как создавать случайные строки из таблицы.

1
ответ дан 26 November 2019 в 20:53
поделиться

, если вы не удаляете строку в этой таблице, наиболее эффективный способ:

(если вы знаете минимальный идентификатор, просто пропустите его)

SELECT MIN(id) AS minId, MAX(id) AS maxId FROM table WHERE 1

$randId=mt_rand((int)$row['minId'], (int)$row['maxId']);

SELECT id,name,... FROM table WHERE id=$randId LIMIT 1
1
ответ дан 26 November 2019 в 20:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: