Выбор случайной строки из БД

  • Автор темы Автор темы step
  • Дата начала Дата начала
Автор оригинала: step
to Viktor_Rez
согласен :)


но лучше, кажется, попробовать как советует Dreammaker
Если в условиях твоей задачи необходимо получить случайное значение двумя запросами к БД, в каждом из которых к тому же есть условие выборки, то тогда согласен, вариант Dreammaker лучше.
 
Хм. А если все то же, но нужно не одно значение получить, а несколько? Не повторять же запросы соответствующее количество раз...
 
Автор оригинала: Dreammaker
PHP:
SELECT id, img_path, url  FROM banners WHERE b_place = 1 AND active = 1 LIMIT $offset, 1
Вот у меня в базе 22 миллиона записей и этот запрос выполняется 10 секунд. Так и должно быть? А мне нужно 100 случайных строк, которые в базе идут не подряд. 1000 секунд - это уже очень много.
Еще варианты есть?
Встречается еще вариант индекса по id и выбирать случайное число между минимальным и максимальным id. У меня этот вариант тоже не применим, т.к. ОЧЕНЬ много больших дырок в id :(
 
как вариант:
PHP:
$ids='';
for ($i=0;$i<200;$i++) {
    $ids .= rand(1,$max_id_v_bd).',';
}
$ids = substr($ids,0,strlen($ids)-1);

SELECT id, img_path, url  FROM banners WHERE b_place = 1 AND active = 1 AND id IN ('.$ids.') LIMIT 0, 100

Код не супер, но главное идею передает)
 
у меня степень заполнения id в диапазоне от 1 до $max_id_v_bd составляет не более 0.1%
т.е. как я написал - МНОГО дыр :(
Такой код в лучшем случае даст в качестве результата одну строку.
 
Labutin
Ну я не думал что настолько много дыр!)
Специально в коде взял в 2 раза больше...
Ну если тут такое дело, то я вижу решение только средствами mysql плюс по максимуму оптимизировать запрос. Впрочем об этом писали уже выше...
 
Mr_Max
Многоуважаемые суперумные гуру, если вы отправляете на конкретную страницу http://phpclub.ru/detail/article/mysql_optimize то, пожалуйста, убедитесь, что там есть ответ на мой вопрос. Про оптимизацию LIMIT там нет ни слова :(
Если отправляете в поиск, то, пожалуйста, убедитесь, что там есть ответ. А поиск дает всего 3 разных варианта ответа на мою проблему (еще четвертый был подкинут на этой странице). А варианты такие:
order by rand()
limit случайное_число,1
выборка по случайному id, если в них нет дыр
и четвертый - выбор по случайному id с запасом, если дыры маленькие
Других вариантов в поиске я не нашел. Вы их там видите?
Мне все эти варианты не подходят :(
Почему мне нельзя после этого создавать новую тему?
 
Labutin
Других вариантов в поиске я не нашел. Вы их там видите?
В поиске в топиках с подобной проблемой я вижу от топик-стартеров EXPLAIN запроса
Об это написано в статье по оптимизации.

Так-же я там вижу
SHOW CREATE TABLE

Соизвольте предоставить эту информацию в Вашем случае

Чем в этой супертяжелой задаче не подошел 2-й вариант?
>limit случайное_число,1
 
Mr_Max
Это было указано в закрытом топике:
PHP:
CREATE TABLE sklad (
  id int(10) unsigned NOT NULL auto_increment,
  maker varchar(30) NOT NULL default '',
  number varchar(30) NOT NULL default '',
  description varchar(255) default NULL,
  quantity varchar(30) NOT NULL default '',
  price_opt double NOT NULL default '0',
  price_opt2 double NOT NULL default '0',
  price_rozn double NOT NULL default '0',
  days varchar(10) default '',
  price_group_id int(10) unsigned NOT NULL default '0',
  provider_id int(11) NOT NULL default '0',
  store_id bigint(20) NOT NULL default '-1',
  PRIMARY KEY  (id),
  KEY number (number),
  KEY provider_id (provider_id),
  KEY store_id (store_id)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251;


EXPLAIN SELECT number FROM sklad LIMIT 17000000 , 1
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE sklad index NULL number 32 NULL 22042038 Using index
Данный запрос выполняется более 10 секунд.

Чем в этом супертяжелой задаче не подошел 2-й вариант?
>limit случайное_число,1
Тем что ОЧЕНЬ долго выполняется. Об этом я написал в своем первом сообщении на данной странице. Если вы отправляете всех по разным URL, почему сами не читаете сообщения тех, кого учите?
 
Labutin
Если вы отправляете всех по разным URL, почему сами не читаете сообщения тех, кого учите?
Дабы они предоставили ВСЮ нужную информацию относительно своей проблемы.

-~{}~ 02.12.07 21:52:

Попробуйте 2-мя запросами
1. SELECT MAX
Потом средставами пхп 10 случайных чисел
потом выборка по id>=$value + UNION

-~{}~ 02.12.07 21:53:

Что мешает "вынести" в отдельную таблицу ячеек так 10000?
И случайные id выбирать именно оттуда?

-~{}~ 02.12.07 21:58:

Можно попробовать "ограничить" выборку по WHERE id>=

-~{}~ 02.12.07 22:38:

Это было указано в закрытом топике:
В закрытом топике нет екслайна
.


-~{}~ 02.12.07 22:39:
1. SELECT MAX(id) FROM table
2. SELECT field FROM table WHERE id >= (RAND()*$max_id) LIMIT 1 + UNION
 
Labutin
Вам указали несколько путей решения вашей проблемы вариант со случайными ИД самый (ИМХО) оптимальный если у вас в таблице много дыр ето уже Ваша проблема, к слову -легко решаемая.
 
Сверху