Выборка 30 случайных строк
Tmin10
Дата: 10.02.2013 13:10:37
Подскажите, как из большой таблицы выбрать 30 случайных строк?
miksoft
Дата: 10.02.2013 21:15:54
расскажите побольше про эту таблицу.
romy4
Дата: 11.02.2013 11:33:36
Tmin10,
Если таблица не имеет разрывов в id, то легко. Если разрывы в 1-2 индекса, то тоже легко
Tmin10
Дата: 11.02.2013 14:27:21
miksoft, Предполагается самый плохой случай, когда таблица не имеет поля id или имеет в нём большие разрывы, не позволяющие использовать это поле корректно для выборки записей с id=rand()
artas
Дата: 11.02.2013 14:37:17
Tmin10,
вас просят рассказать про таблицу - количество значени и тд. В самом простом лучае когда немного записей подойдет order by rand limit 30, если же записей много то и задача решается другим способом
DBConstructor
Дата: 12.02.2013 02:50:51
словесное описание "бескурсорного" варианта:
1. создаем пустую временную таблицу такой же структуры, как исходная;
2. в цикле получаем случайное число функцией RAND() от количества записей исходной таблицы;
3. в подзапросе на выборку с условием "отсутствует во временной таблице" лимитируем случайным числом количество отбираемых строк;
4. из подзапроса лимитируем отбор одной записи с обратной сортировкой по уникальному полю и помещаем эту строку во временную таблицу;
5. повторяем цикл 30 раз;
-------------------------------
по завершении, имеем во временной таблице случайные 30 строк исходной
romy4
Дата: 12.02.2013 13:52:42
DBConstructor, Tmin10,
Можно ещё 30 unions с лимитом 1 и рандомным офсетом. В лоб и достаточно быстро.
miksoft
Дата: 12.02.2013 13:56:36
| romy4 |
|---|
DBConstructor, Tmin10, Можно ещё 30 unions с лимитом 1 и рандомным офсетом. В лоб и достаточно быстро. |
Ни в коем случае. 30 рандомных офсетов никак быстро быть не может.
order by rand() limit 30 и то, наверное, быстрее окажется.
romy4
Дата: 12.02.2013 14:06:02
miksoft,
вы ошибаетесь.
пример. база 200к слов myisam, primary key (`id`)
SELECt * FROM `wordbase` ORDER BY RAND() LIMIT 30;
скорость 0,593 сек
(SELECT * FROM `wordbase` LIMIT 1 OFFSET 30)
UNION
(SELECT * FROM `wordbase` LIMIT 1 OFFSET 533)
UNION
(SELECT * FROM `wordbase` LIMIT 1 OFFSET 1030)
UNION
(SELECT * FROM `wordbase` LIMIT 1 OFFSET 8630)
UNION
(SELECT * FROM `wordbase` LIMIT 1 OFFSET 14923)
UNION
(SELECT * FROM `wordbase` LIMIT 1 OFFSET 15983)
UNION
(SELECT * FROM `wordbase` LIMIT 1 OFFSET 19954)
UNION
(SELECT * FROM `wordbase` LIMIT 1 OFFSET 21874)
UNION
(SELECT * FROM `wordbase` LIMIT 1 OFFSET 25874)
UNION
(SELECT * FROM `wordbase` LIMIT 1 OFFSET 30584)
UNION
(SELECT * FROM `wordbase` LIMIT 1 OFFSET 34883)
UNION
(SELECT * FROM `wordbase` LIMIT 1 OFFSET 38093)
UNION
(SELECT * FROM `wordbase` LIMIT 1 OFFSET 41857)
UNION
(SELECT * FROM `wordbase` LIMIT 1 OFFSET 43895)
UNION
(SELECT * FROM `wordbase` LIMIT 1 OFFSET 58433)
UNION
(SELECT * FROM `wordbase` LIMIT 1 OFFSET 59043)
UNION
(SELECT * FROM `wordbase` LIMIT 1 OFFSET 59302)
UNION
(SELECT * FROM `wordbase` LIMIT 1 OFFSET 59999)
UNION
(SELECT * FROM `wordbase` LIMIT 1 OFFSET 60302)
UNION
(SELECT * FROM `wordbase` LIMIT 1 OFFSET 60431)
UNION
(SELECT * FROM `wordbase` LIMIT 1 OFFSET 66954)
UNION
(SELECT * FROM `wordbase` LIMIT 1 OFFSET 67439)
UNION
(SELECT * FROM `wordbase` LIMIT 1 OFFSET 75403)
UNION
(SELECT * FROM `wordbase` LIMIT 1 OFFSET 78434)
UNION
(SELECT * FROM `wordbase` LIMIT 1 OFFSET 85420)
UNION
(SELECT * FROM `wordbase` LIMIT 1 OFFSET 99543)
UNION
(SELECT * FROM `wordbase` LIMIT 1 OFFSET 103492)
UNION
(SELECT * FROM `wordbase` LIMIT 1 OFFSET 134294)
UNION
(SELECT * FROM `wordbase` LIMIT 1 OFFSET 159534);
0,219 сек
поверьте, rand() очень долгая функция совместно с сортировкой.
romy4
Дата: 12.02.2013 14:13:10
Tmin10,
Если нет primary key `id` в таблице, то сделайте его. Сами разрабы мускуля в мануале рекомендуют его использовать. Он необходим для оптимизации запросов. Разве что кроме редких случаев, когда таблица состоит из двух полей для связи айдишников