рандомизация большого набора данных - PullRequest
2 голосов
/ 24 августа 2010

Я пытаюсь найти способ получить случайный выбор из большого набора данных.

Мы ожидаем, что набор вырастет до ~ 500K записей, поэтому важно найти способ, который будет продолжать работать хорошо, пока набор растет.

Я испробовал технику из: http://forums.mysql.com/read.php?24,163940,262235#msg-262235 Но это не совсем случайно и не очень хорошо с предложением LIMIT, вы не всегда получаете желаемое количество записей.

Так что я подумал, поскольку PK - это auto_increment, я просто генерирую список случайных идентификаторов и использую предложение IN, чтобы выбрать нужные мне строки. Проблема с этим подходом состоит в том, что иногда мне нужен случайный набор данных с записями, имеющими специфический статус, статус, который находится не более чем в 5% от общего набора. Чтобы это работало, мне сначала нужно выяснить, какой идентификатор я могу использовать, который имеет этот определенный статус, так что это тоже не сработает.

Я использую mysql 5.1.46, механизм хранения MyISAM.
Может быть важно знать, что запрос на выбор случайных строк будет выполняться очень часто, а таблица, из которой он выбирается, часто добавляется.

Любая помощь будет принята с благодарностью!

Ответы [ 3 ]

2 голосов
/ 24 августа 2010

Вы можете решить эту проблему с помощью некоторой денормализации:

  • Создайте вторичную таблицу, которая содержит те же ключи и статусы, что и ваша таблица данных
  • Добавить и заполнить столбец группы состояний, который будет своего рода подпунктом, который вы автоматически нумеруете (автоинкремент на основе 1 относительно одного статуса)
Pkey    Status    StatusPkey
1       A         1
2       A         2
3       B         1
4       B         2
5       C         1
...     C         ...
n       C         m (where m = # of C statuses)

Если вам не нужно фильтровать, вы можете генерировать rand #s на pkey, как вы упоминали выше. Когда вам действительно нужно отфильтровать, генерируйте ранды против StatusPkeys с определенным интересующим вас статусом.

Есть несколько способов создать эту таблицу. У вас может быть процедура, которую вы запускаете с интервалом, или вы можете сделать это вживую. Последнее может привести к снижению производительности, поскольку вычисление StatusPkey может стоить дорого.

1 голос
/ 24 августа 2010

Ознакомьтесь с этой статьей от Jan Kneschke ... Она отлично объясняет все плюсы и минусы различных подходов к этой проблеме ...

0 голосов
/ 24 августа 2010

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

Сначала получите случайное смещение, масштабированное по количеству строк, соответствующих вашим 5% условиям:

SELECT ROUND(RAND() * (SELECT COUNT(*) FROM MyTable WHERE ...conditions...))

Возвращает целое число.Затем используйте целое число в качестве смещения в выражении LIMIT:

SELECT * FROM MyTable WHERE ...conditions... LIMIT 1 OFFSET ?

Не все проблемы должны решаться в одном запросе SQL.

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