![]() |
Развлекаемся с SQL
Ставим задачи - находим эффектные решения.
(В базе MySQL) 1. Виртуальный колхоз "Кизил пиёз. Пять бригад каждый день сдают на склад пиёз в кг. Текущий отчёт: За день. За неделю. За месяц. За квартал. За год. ps. Без флейма плиз. Красивые решения плюсуем. |
2. Дано 1М записей;
Не самый производительный сервер; Нужно: ORDER BY RAND() LIMIT 10; В качестве временного решения работает: Первый запрос: узнаем количество записей в базе ($min, $max) В PHP генерим 10 "случайных" индексов: $id[$i] = rand($min, $max); Второй запрос: UNION (SELECT * FROM `a` WHERE `id` = $id[0] LIMIT 1) UNION (SELECT * FROM `a` WHERE `id` = $id[1] LIMIT 1)… и так далее. Проверяем результат, если записи по одному из ID не было (в ID бывают "дырки"), и получили меньше чем 10, добираем нужное количество запросов. Такая штуковина работает быстро (в сотни, и даже тысячи раз быстрее родного BY RAND()), но неэстетично. :) |
`id` in уже не ?
|
Я как-то работал с записями больше чем 1М, там я реализовал "сложную (с relations)" выборку через временные таблицы. Работает не то что быстро, а моментально.
|
Цитата:
Или это к вопросу №1 было? |
Нет, Руслан. Это к вашей задачи решение. Спокойно можно использовать ORDER BY RAND() + дополнительные маневры в виде where, group, join
|
Цитата:
Здесь его нет, только слово «маневры». :) |
Зачем узнавать max если дано 1М записей?
Какое практическое значение у order by rand()? Сортировка по случайному значению? Ну в общем читабельно тут http://hudson.su/2010/09/16/mysql-optimizaciya-order-by-rand/ |
Цитата:
Элементы добавляются/удаляются. Цитата:
|
Примерно так можно работать с большим объемом данных, где нужно делать выборки:
create temporary table`temp` select * `db` .... , дальше уже обращаться ко временной таблице select .. from `temp` |
Цитата:
Можно подробнее? |
Скорость Руслан, Скорость. Это альтернатива вашему временному решению.
После чего можно смело писать select * fromt temp order by rand() |
Цитата:
Но за идею спасибо, нужно будет апробировать на практике. :187: |
Мне понравился ответ с выборкой по номерам строк, которые не могут быть с дырами.
Предложение. Давайте примеры ближе к жизни. Нас люди (молодые патриоты) читают. ;) Для специфики есть гугл или хабр. |
Перебор базы в памяти работает во много раз быстрее, попробуйте, возможно, вы и не заметите задержки при рандомной выборки
|
Цитата:
|
Цитата:
Цитата:
|
Цитата:
|
ну, это да, к ~ для 1млн записей (таблица, в которой есть поле `text`) требуется 1GB RAM.
Мой способ это скорее исключение, чем правило для использования. Он будет оправдан, если с этой таблицой будут происходит несколько манипуляций, но и для order by random() вполне подойдет, мне кажется. |
Руслан, у меня как раз есть подопытная таблица от форума gamertalk.uz (около 0.5М постов)
Завтра потестю и ваш и свой вариант. Результат скинут сюды. |
Цитата:
|
имеется ввиду "дыры" - что запись удалили, при условии что там AI в таком режиме работает, что не заполняет удаленные ID
|
Цитата:
Кстати есть скрипты забить базу данными для теста? С возможностью выбора кол строк? |
Цитата:
|
Цитата:
Скрытый текст:
Интересные строки тут: 28 и 124. В 28-ой строчке настраиваем доступ к базе (обязательно рут, либо чтобы были права на создание базы и таблиц, ну и собственно на инсерт) На 124 строке указываем кол-во строк, которое надо вбить в базу. :187: |
О! Респект!
Сейчас прогоним. |
Цитата:
Создано 99 строк при 100. Создано 990 строк при 1000. ;) |
Цитата:
|
Итак, результаты по трем методам выборок из базы,в которой > 1млн записей, и имеется поле text:
http://i.pro-wizard.ru/test/select_db_tablerows.png
Вот скрипт для тестов: Скрытый текст:
|
Цитата:
2. 0.14 с 3. 207.8 с Вполне логично, спасибо. |
Цитата:
|
Может кто затестит все три теста на мощном linux сервере? Интересно результаты посмотреть ))
|
Цитата:
Минус в том, что если "дырок" в ID много, то пока получишь 10 (а если нужно 100-1000) элементов, то цикл может повторяться значительное количество раз… Еще минус, что нет возможности добавить дополнительное условие, ведь вытаскивается конкретная запись по ID. В итоге имеем, что часто оптимален родной RAND(). :187: |
Если это условие одинаков для всех найденных айди, то его можно использовать. Если нет, то тогда и запрос надо по-другому строить.
|
Я так и не понял, почему создание временной таблицы должно было уменьшить время выборки?
Мускуль ведь для этого создает временный файл и пишет туда данные. Отсюда и временные затраты |
файл != оперативная память (ram)
|
Цитата:
|
Тогда наверное я неправильно вашего вопроса понял
|
На
mysql> select max(id) as maxid from test; +-------+ | maxid | +-------+ | 1980 | +-------+ 1 row in set (0.00 sec) 1. Rand = 0.09 2. Script = 0 3. Temptable =0.31 Для mysql> select max(id) as maxid from test; +-------+ | maxid | +-------+ | 99 | +-------+ 1 row in set (0.00 sec) 1. Rand = 0.02 2. Script = 0 3. Temptable =0.04 |
Цитата:
Цитата:
|
| Текущее время: 02:02. Часовой пояс GMT +5. |
Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод:
OOO «Единый интегратор UZINFOCOM»