Javascript-форум (https://javascript.ru/forum/)
-   Оффтопик (https://javascript.ru/forum/offtopic/)
-   -   Перемешать данные в таблице (https://javascript.ru/forum/offtopic/17325-peremeshat-dannye-v-tablice.html)

greatilya 14.05.2011 23:12

Перемешать данные в таблице
 
В БД MySQl имеется таблица состоящая из 1 столбца/поля `word` varchar(60) NOT NULL, на этом столбце стоит стоит первичный ключ.
В таблице 12млн записей.
Не могу придумать оптимального решения для того, чтобы вытащить случайную запись. Т.к. таблица большая, то ORDER BY RAND очень и очень долго выполняется.
Попробовал еще таким способом: SELECT `word` FROM `words` LIMIT N, 1, где N - случайное число от 0 до 12млн. Подобный запрос выполняется за 8 секунд, что так же меня не устраивает.

Как вариант вижу создание дополнительного столбца наполненного случайными числами от 0 до 12 млн. А после сортировать поле по возрастанию, и брать по 1 записи с начала и удалять её после обработки.

Есть ли какие-то идеи/советы как решить задачку оптимальнее?

monolithed 14.05.2011 23:51

не знаю на сколько быстрей, но как-то так:
$query = mysql_query("SELECT * FROM words");
$id = rand(1, mysql_num_rows($query));
$sql = "SELECT word FROM words WHERE id=$id";

greatilya 15.05.2011 18:18

monolithed,
Если бы у меня была бы колонка id то проблем бы не было. Если мы добавляем колонку с id то нам необходимо её сделать первичным ключом. При этом мы потеряем скорость при поиске по колонке word, причем не просто потеряем, а у нас полностью пропадет данная возможность (т.к. ставя даже ключ UNIQUE время поиска превысило 30 секунд). Хотя для других реализаций ваш способ вполне подходит, только важно поддерживать отсутствие дыр в индексе id.

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

dmitriymar 15.05.2011 20:02

greatilya,
правильно организовать базу данных.на текст вешать первичный ключ и по нему поиск-круто...хотя бы изза того что поиск по тексту самый медленный .файл текстовый и то быстрее будет работать-сместиться на строку н и считать её....
не правильная организация бд. перебор всего..... многотабличность как вариант чтоб ключи все не ковырять и вложенные запросы...и всё равно столбец с номером ускорит поиск

x-yuri 16.05.2011 12:38

т.е. PRIMARY KEY(word) - нормально, а UNIQUE(word) - больше 30 сек?

greatilya 16.05.2011 13:43

Цитата:

Сообщение от x-yuri
т.е. PRIMARY KEY(word) - нормально, а UNIQUE(word) - больше 30 сек?

Ну да, только правда при LIKE, без %.

Нашел решение ситуации, распишу поэтапно:
1) убрал PRIMARY KEY с word
2) добавил колонку id AUTOINCREMENT PRIMARY KEY
3) убрал PRIMARY KEY с id
4) поставил PRIMARY KEY на word
5) поставил UNIQUE на id
Итого получилась таблица, где все слова пронумерованы с 1 до 12млн. Теперь для поиска случайного слова мы берем случайное число от 1 до 12млн и вот у нас id нужной записи. При ключе UNIQUE на id поиск достаточно быстрый. Остается только следить за отсутствием дыр в нумерации id.

Если я где-то ошибся в структуре, оптимизации или еще в чем-то, то просьба меня поправить.

x-yuri 16.05.2011 20:50

Я в этом пока слабо разбираюсь, чтобы советовать, но, возможно, при таких обьемах стоит подумать в сторону nosql-решений (mongodb, cassandra, couchdb).

greatilya 18.05.2011 09:02

x-yuri,
ну то решение к которому я пришел вполне получилось оптимизированным. Задача не настолько существенная чтобы воротить туда разнообразные навороченности.

x-yuri 18.05.2011 17:50

я считаю, что навороченность - это оптимизация, в отличие от использования более подходящих инструментов. Но деталей проекта я не знаю, поэтому сложно что-то сказать


Часовой пояс GMT +3, время: 17:48.