Перемешать данные в таблице
В БД 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 записи с начала и удалять её после обработки. Есть ли какие-то идеи/советы как решить задачку оптимальнее? |
не знаю на сколько быстрей, но как-то так:
$query = mysql_query("SELECT * FROM words"); $id = rand(1, mysql_num_rows($query)); $sql = "SELECT word FROM words WHERE id=$id"; |
monolithed,
Если бы у меня была бы колонка id то проблем бы не было. Если мы добавляем колонку с id то нам необходимо её сделать первичным ключом. При этом мы потеряем скорость при поиске по колонке word, причем не просто потеряем, а у нас полностью пропадет данная возможность (т.к. ставя даже ключ UNIQUE время поиска превысило 30 секунд). Хотя для других реализаций ваш способ вполне подходит, только важно поддерживать отсутствие дыр в индексе id. Вариант с добавлением колонки со случайным числом тоже не дал никаких результатов. Даже после установки индекса на эту колонку, время запроса с сортировкой по этой колонке составляет более 10 секунд. |
greatilya,
правильно организовать базу данных.на текст вешать первичный ключ и по нему поиск-круто...хотя бы изза того что поиск по тексту самый медленный .файл текстовый и то быстрее будет работать-сместиться на строку н и считать её.... не правильная организация бд. перебор всего..... многотабличность как вариант чтоб ключи все не ковырять и вложенные запросы...и всё равно столбец с номером ускорит поиск |
т.е. PRIMARY KEY(word) - нормально, а UNIQUE(word) - больше 30 сек?
|
Цитата:
Нашел решение ситуации, распишу поэтапно: 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. Если я где-то ошибся в структуре, оптимизации или еще в чем-то, то просьба меня поправить. |
Я в этом пока слабо разбираюсь, чтобы советовать, но, возможно, при таких обьемах стоит подумать в сторону nosql-решений (mongodb, cassandra, couchdb).
|
x-yuri,
ну то решение к которому я пришел вполне получилось оптимизированным. Задача не настолько существенная чтобы воротить туда разнообразные навороченности. |
я считаю, что навороченность - это оптимизация, в отличие от использования более подходящих инструментов. Но деталей проекта я не знаю, поэтому сложно что-то сказать
|
Часовой пояс GMT +3, время: 10:56. |