Как я могу использовать эффективный простой случайный образец в SQL? В этой базе данных работает MySQL; моя таблица составляет не менее 200 000 строк, и я хочу, чтобы простая случайная выборка составляла около 10 000.Простые случайные образцы из базы данных Sql
«очевидный» ответ заключается в следующем:
SELECT * FROM table ORDER BY RAND() LIMIT 10000
Для больших таблиц, это слишком медленно: он вызывает RAND() для каждой строки (что уже ставит его в точке О (п)) и сортирует их , что делает его O (n lg n) в лучшем случае. Есть ли способ сделать это быстрее, чем O (n)?
Примечание: Как Эндрю Мао указывает в комментариях, если вы используете этот подход на SQL Server, вы должны использовать функцию NEWID T-SQL(), так как RAND() may return the same value for all rows.
EDIT: 5 ЛЕТ СПУСТЯ
я снова столкнулся с этой проблемой с большим столом, и в конечном итоге, используя версию @ решение невежественных лет, с двумя ухищрениями:
- Sample Ряды до 2-5x мой желаемый размер выборки, дешево ORDER BY RAND()
- Сохраните результат RAND() в индексированном столбце при каждой вставке/обновлении. (Если ваш набор данных не очень тяжелый для обновления, вам может потребоваться найти другой способ сохранить этот столбец свежим.)
Чтобы взять образец из 1000 элементов таблицы, я подсчитываю строки и примеры результат вниз, в среднем, 10000 строк с колонки frozen_rand:
SELECT COUNT(*) FROM table; -- Use this to determine rand_low and rand_high
SELECT *
FROM table
WHERE frozen_rand BETWEEN %(rand_low)s AND %(rand_high)s
ORDER BY RAND() LIMIT 1000
(Моя фактическая реализация включает в себя больше работы, чтобы убедиться, что я не undersample и вручную завернуть rand_high вокруг, но основная идея «случайным образом сокращает ваш N до нескольких тысяч».)
Хотя это приносит некоторые жертвы, это позволяет мне делать оставьте базу данных вниз с помощью сканирования индекса, пока она не станет достаточно маленькой для ORDER BY RAND().
Это даже не работает в сервере SQL, потому что `RAND()` возвращает то же значение каждый последующий вызов. – 2012-09-20 16:43:03
Хорошая мысль. Я добавлю, что пользователи SQL Server должны использовать ORDER BY NEWID(). – ojrac 2012-09-20 19:14:16
Он все еще ужасно неэффективен, потому что он должен сортировать все данные. Метод случайной выборки для некоторого процента лучше, но я даже после чтения кучи сообщений здесь, я не нашел приемлемого решения, которое достаточно случайное. – 2012-09-20 21:11:39