Извлечение строк RAND () без ORDER BY RAND () всего за один запрос - PullRequest
2 голосов
/ 22 июля 2010

Использование RAND () в MySQL для получения одной случайной строки из огромной таблицы очень медленное:

SELECT quote FROM quotes ORDER BY RAND() LIMIT 1

Вот статья об этой проблеме и почемуслучай.

Их решение состоит в том, чтобы использовать два запроса:

SELECT COUNT(*) AS cnt FROM quotes

- Use result to generate a number between 0 and COUNT(*)

SELECT quote FROM quotes LIMIT $generated_number, 1

Мне было интересно, будет ли это возможно только в одном запросе.

Так что мой подход был:

SELECT * FROM quotes
LIMIT (
  ROUND(
    (SELECT COUNT(*) FROM quotes) * RAND()
  )
), 1

Но в MySQL он не допускает никакой логики в пределах Limit.Хотя я не могу найти никакой информации по этой теме, правда ли это.

Итак, мои вопросы:

  1. Как я могу использовать RAND () в LIMIT?
  2. Знаете ли вы какой-либо другой способ решить эту проблему всего одним запросом?

Ответы [ 3 ]

5 голосов
/ 22 июля 2010

Существует ли причина, по которой хранимая процедура не может использоваться для создания подготовленного оператора?

DELIMITER //
DROP PROCEDURE IF EXISTS rand_quote//
CREATE PROCEDURE rand_quote()
BEGIN
    SET @rand := ROUND((SELECT COUNT(*) FROM quotes) * RAND());
    SET @sql := CONCAT('SELECT * FROM quotes LIMIT ', @rand, ', 1');
    PREPARE stmt FROM @sql;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
END;
//
DELIMITER ;
1 голос
/ 15 марта 2015

Я решил проблему, проверив max id.Затем я сделал php цикл rand (0, max_id), который проверяет, существует ли объект.Готово.

Гораздо быстрее, чем предыдущий порядок рандов.

1 голос
/ 22 июля 2010

Я только что изобразил это, швы как решение:

SELECT * FROM quotes
WHERE quotes_id = ROUND(
  (SELECT COUNT(*) FROM quotes) * RAND()
)
LIMIT 1

Но это будет работать, только если в quotes_id нет пробелов.

...