powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / Выбор случайных фото
34 сообщений из 34, показаны все 2 страниц
Выбор случайных фото
    #32872147
TigranE
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Таблица базы данных содержит фотографии товаров, каждая запись в таблице имеет два поля - id(первичный ключ) и good_id(внешний ключ к соответствующей записи в таблице товаров). Необходимо случайным образом выбрать RAND_PHOTOS_NUM (напр. 3) фотографий. Выбранные фотографии не должны повторятсья. Общее число фотографий в таблице может оказаться меньше RAND_PHOTOS_NUM.

Написал следующий код, но мне кажется все можно сделать гораздо проще. Пожалуйста посоветуйте как оптимизировать приведенный отрывок кода или скажите другое решение. Спасибо.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
  $photos=array();
  $res=mysql_query('select * from '.TBL_PHOTOS) or die(mysql_error());
  while($row=mysql_fetch_assoc($res))
    $photos=$row
  $num_photos=count($photos);
  $rand_photos=array();
  $max_iters= 20 ;
  if ($num_photos> 0 )
  {
    $j= 0 ;
    while($j<RAND_PHOTOS_NUM)
    {
      $k= 0 ;
      while(array_key_exists($rand_val, $rand_photos) && $k< 20 )
      {
        $rand_val=mt_rand( 0 , $num_photos- 1 );
        $rand_photos[$j]=$photos[$rand_val];
        $k++;
      }
      $j++;
    }
  }
  
...
Рейтинг: 0 / 0
Выбор случайных фото
    #32872197
*
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
*
Гость
TigranEмне кажется все можно сделать гораздо проще.Не проще, а правильнее$res=mysql_query('select * from '.TBL_PHOTOS) or die(mysql_error());Незачем запрашивать ВСЮ базу данных, чтобы выбрать из неё три элемента.
Код:
1.
2.
$res = mysql_query('SELECT COUNT(*) as cnt FROM '.TBL_PHOTOS);
$data = mysql_fetch_assoc($res);
$res = mysql_query('SELECT * FROM '.TBL_PHOTOS.' LIMIT '.mt_rand(0,$data['cnt']-1);
ну и т.д.
...
Рейтинг: 0 / 0
Выбор случайных фото
    #32872399
Фотография 4m@t!c
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
*Незачем запрашивать ВСЮ базу данных, чтобы выбрать из неё три элемента.
Код:
1.
2.
3.
4.
5.
$res = mysql_query('SELECT COUNT(*) as cnt FROM '.TBL_PHOTOS);

что бы подсчитать кол-во элементов - перебирается вся база
 *
$data = mysql_fetch_assoc($res);
$res = mysql_query('SELECT * FROM '.TBL_PHOTOS.' LIMIT '.mt_rand(0,$data['cnt']-1);
ну и т.д.
Я понимаю, что нет такого понятий, как "первый элемент БД", "последний элемент БД". Есть просто строка и идентификатор этого поля(не всегда). Если таблица с картинками не обновляется, то запрос будет выбриать одни и те же n-первых фото.
...
Рейтинг: 0 / 0
Выбор случайных фото
    #32872467
Фотография hell
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А так?)

Код: plaintext
1.
select distinct  x from table order by rand() limit  3 

В этом плане MySQL очень удобен

"The CBO without stats is like a morning without coffee." T.Kyte
...
Рейтинг: 0 / 0
Выбор случайных фото
    #32873009
DocAl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
4m@t!c
что бы подсчитать кол-во элементов - перебирается вся база

База (а, точнее, таблица) перебирается для подсчёта количества элементов только при отсутствии подходящего индекса.
...
Рейтинг: 0 / 0
Выбор случайных фото
    #32873012
DocAl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hellА так?)

Код: plaintext
1.
select distinct  x from table order by rand() limit  3 

В этом плане MySQL очень удобен

"The CBO without stats is like a morning without coffee." T.Kyte
Выглядит изячно, но не будет ли такой запрос использовать временную таблицу?...
...
Рейтинг: 0 / 0
Выбор случайных фото
    #32873044
Фотография 4m@t!c
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DocAl 4m@t!c
что бы подсчитать кол-во элементов - перебирается вся база

База (а, точнее, таблица) перебирается для подсчёта количества элементов только при отсутствии подходящего индекса.
гы-гы.. да с "базой" - это я конечно лопухнул. А насчет индекса - индекс же должен быть в условии, а если нет условия, то речь же за индекс не идет.
...
Рейтинг: 0 / 0
Выбор случайных фото
    #32873075
*
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
*
Гость
4m@t!c *Незачем запрашивать ВСЮ базу данных, чтобы выбрать из неё три элемента.
Код:
1.
2.
$res = mysql_query('SELECT COUNT(*) as cnt FROM '.TBL_PHOTOS);что бы подсчитать кол-во элементов - перебирается вся база[/quote]Не понял юмора. Это объяснение того, что делалось в оригинале или что?[quot  *]
$data = mysql_fetch_assoc($res);
$res = mysql_query('SELECT * FROM '.TBL_PHOTOS.' LIMIT '.mt_rand(0,$data['cnt']-1);
ну и т.д.
Я понимаю, что нет такого понятий, как "первый элемент БД", "последний элемент БД". Есть просто строка и идентификатор этого поля(не всегда). Если таблица с картинками не обновляется, то запрос будет выбриать одни и те же n-первых фото.Да, ошибочка вышла, забыл указать второй параметр после запятой (почему-то решил, что первый параметр - номер записи, а не количество). А по поводу остального добавить нужный ORDER BY, надеюсь, труда не составит?
...
Рейтинг: 0 / 0
Выбор случайных фото
    #32873081
*
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
*
Гость
По поводу ORDER BY RAND читайте ман.
...
Рейтинг: 0 / 0
Выбор случайных фото
    #32873123
DocAl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ман штука хорошая, но именно тут он ничего особо полезного не сказал.
Запрос работает, да, делает то, что нужно.
Но про то, что такой запрос будет создавать временную таблицу не сказано, а это, увы, факт..( Со всем вытекающими в случае, если таблица большая...
...
Рейтинг: 0 / 0
Выбор случайных фото
    #32873371
*
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
*
Гость
Да пёс с ней, с временной таблицейВ выражениях вида ORDER BY не следует использовать столбец с величинами RAND(), поскольку применение оператора ORDER BY приведет к многократным вычислениям в этом столбце.
...
Оператор RAND() не следует воспринимать как полноценный генератор случайных чисел...Этого достаточно, чтобы не использовать ORDER BY RAND
Ещё помнится бывали глюки на 3.x версии с тем, что выбиралось одно и то же (не каждый раз одно и то же, но довольно часто, да и периуд был небольшим).
...
Рейтинг: 0 / 0
Выбор случайных фото
    #32873390
TigranE
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
блинЫ, пришли туда откуда начали :) так что мне делать с этими случайными фото?
...
Рейтинг: 0 / 0
Выбор случайных фото
    #32873442
*
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
*
Гость
TigranEблинЫ, пришли туда откуда начали :) так что мне делать с этими случайными фото?Я же всё написал - выбираете COUNT'ом количество записей, потом при помощи PHP генерируете нужное число случайных чисел и достаёте записи в указанных позициях (LIMIT rnd,1) при некотором способе сортировки (ORDER BY id, к примеру). Да, это требует N+1 запрос к базе - если кто-нибудь знает более простой и надёжный способ - было бы интересно услышать (жаль нельзя доставать из базы сразу из нескольких диапазонов, типа LIMIT x,1,y,1,z,1)
...
Рейтинг: 0 / 0
Выбор случайных фото
    #32873465
TigranE
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
*Я же всё написал - выбираете COUNT'ом количество записей, потом при помощи PHP генерируете нужное число случайных чисел и достаёте записи в указанных позициях (LIMIT rnd,1) при некотором способе сортировки (ORDER BY id, к примеру). Да, это требует N+1 запрос к базе - если кто-нибудь знает более простой и надёжный способ - было бы интересно услышать (жаль нельзя доставать из базы сразу из нескольких диапазонов, типа LIMIT x,1,y,1,z,1)

Так что-ли? Поправьте новичка плиз :)

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
  $res=mysql_query('select count(*) from '.TBL_PHOTOS) or die(mysql_error());
  $num_photos=mysql_result($res,  0 ,  0 );
  $max_iters= 20 ;
  $rand_photos=array();
  $rand_vals=array();
  for ($i= 0 ; $i<RAND_PHOTOS_NUM; $i++)
  {
    $k= 0 ;
    do {
      $rand_val=mt_rand( 0 , $num_photos- 1 );
      $k++;
    } while(in_array($rand_val, $rand_vals) && $k<$max_iters);
    $rand_vals[]=$rand_val;

    $res=mysql_query('select * from '.TBL_PHOTOS.
      " order by id limit $rand_val, 1") or die(mysql_error());
    if ($row=mysql_fetch_assoc($res))
      $rand_photos[]=$row;
  }
...
Рейтинг: 0 / 0
Выбор случайных фото
    #32873466
TigranE
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
кстати при чем тут "order by"?
...
Рейтинг: 0 / 0
Выбор случайных фото
    #32873467
*
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
*
Гость
TigranEТак что-ли? Поправьте новичка плиз :)Оно работает? Значит похоже. Оно не работает? PHP FAQ: Ничего не работает! Что делать??? (хотя похоже вы с ним знакомы ;) )
2 TigranE : PHP FAQ: MySQL. Просто и понятно.
...
Рейтинг: 0 / 0
Выбор случайных фото
    #32874270
Армянка
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
По темe выбора случайных строк из таблицы MYSQL запросом:

Код: plaintext
select * from tablename order by rand(unix_timestamp()) limit  1 
Подобный запрос подойдет для небольших таблиц, если же таблица содержит
несколько сот тысяч записей запрос будет работать медлено т.к. MySQL будет
обрабатывать все записи таблицы, расладывая их в случайном порядке и только
после этого выбирая первую запись в полученной очередности. Все это, конечно,
требует определенного времени. В случае, если у вас есть хотя бы одно поле
типа auto_increment, для создания более быстрого запроса можно поступить
следующим образом:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
  $res=mysql_query('select min(id), max(id) from '.TBL_PHOTOS)
    or die(mysql_error());
  $min_id=mysql_result($res,  0 ,  0 );
  $max_id=mysql_result($res,  0 ,  1 );
  $rand_id=rand($min_id, $max_id);
  $res=mysql_query('select * from '.TBL_PHOTOS." where id>=$rand_id limit 1")
    or die(mysql_error());
  if ($row=mysql_fetch_assoc($res))
  {
    extract($row);
    ........
    ........
  }

P.S. Тигран джан, я нечто подобное уже варила для сайта кока-колы, если ничего
не выйдет позвони, отмылю.
...
Рейтинг: 0 / 0
Выбор случайных фото
    #32874279
Фотография hell
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
*Этого достаточно, чтобы не использовать ORDER BY RAND
Ещё помнится бывали глюки на 3.x версии с тем, что выбиралось одно и то же (не каждый раз одно и то же, но довольно часто, да и периуд был небольшим).

http://dev.mysql.com/doc/mysql/ru/LIMIT_optimisation.html]про LIMIT


Если LIMIT # используется с ORDER BY, MySQL закончит сортировку, как только найдет первые # строк, вместо того, чтобы сортировать всю таблицу.


Т.е. по идее для LIMIT 3 строк думаю не очень страшно 3 вызова RAND() :-)

Хотя проверить не могу.
Насчет временной таблицы - сортировка так или иначе использует временную таблицу(если индекса нет, конечно)
...
Рейтинг: 0 / 0
Выбор случайных фото
    #32874315
*
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
*
Гость
hellТ.е. по идее для LIMIT 3 строк думаю не очень страшно 3 вызова RAND() :-)И как вы себе это представляете? Для начала необходимо каждой записи сопоставить случайное число, а у вас же получается взял первые попавшиеся три записи и забыл (это бы ещё ничего, если бы они действительно всегда получались случайными).
2 Армянка , опять же не хватает ORDER BY (хотя не знаю, насколько оно всё же необходимо - спорный вопрос), а из-за привязки к id получается неравномерное распределение (и вообще малопонятно что из-за отсутсвия ORDER BY) - представьте гипотетическую ситуацию - в базе всего две записи, с id = 1 и c id = 1000 - как вы думаете, какая из них в вашем случае будет выпадать чаще? ;)
Вот и получается, что те записи, до которых есть большой промежуток, будут "выпадать" чаще, чем те, которые идут подряд.
...
Рейтинг: 0 / 0
Выбор случайных фото
    #32874440
Армянка
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Переписываем с учетом справедливого замечания г-на * :)

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
$res=mysql_query('select min(id), max(id) from '.TBL_PHOTOS)
    or die(mysql_error());
  $min_id=mysql_result($res,  0 ,  0 );
  $max_id=mysql_result($res,  0 ,  1 );
  $rand_id=mt_rand($min_id, $max_id);

  $sign = mt_rand( 0 ,  1 ) ? '>=' : '<';

  $res=mysql_query('select * from '.TBL_PHOTOS." where id $sign $rand_id limit 1")
    or die(mysql_error());
  if ($row=mysql_fetch_assoc($res))
  {
    extract($row);
    ........
    ........
  }
 
...
Рейтинг: 0 / 0
Выбор случайных фото
    #32874521
*
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
*
Гость
[quot Армянка]Переписываем с учетом справедливого замечания г-на * :)[/quote]Судя по всему - вы его не поняли.
...
Рейтинг: 0 / 0
Выбор случайных фото
    #32874579
Армянка
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
*[quot Армянка]Переписываем с учетом справедливого замечания г-на * :)[/quote]Судя по всему - вы его не поняли.

так просветите великодушно :))
...
Рейтинг: 0 / 0
Выбор случайных фото
    #32874601
*
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
*
Гость
Армянкатак просветите великодушно :))Просто прочтите ещё раз внимательно - от дыр и неравномерности вы так не избавитесь
...
Рейтинг: 0 / 0
Выбор случайных фото
    #32875283
Фотография hell
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
*Я же всё написал - выбираете COUNT'ом количество записей, потом при помощи PHP генерируете нужное число случайных чисел и достаёте записи в указанных позициях (LIMIT rnd,1) при некотором способе сортировки (ORDER BY id, к примеру). Да, это требует N+1 запрос к базе - если кто-нибудь знает более простой и надёжный способ - было бы интересно услышать (жаль нельзя доставать из базы сразу из нескольких диапазонов, типа LIMIT x,1,y,1,z,1)

Согласен, rand() будет выполнятся для всех случаев. Но и в вашем случае будет происходить полное сканирование таблицы/индекса:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
mysql> EXPLAIN select id from bugs.mantis_bug_table ORDER BY id LIMIT  5 , 1 ;
+------------------+-------+---------------+---------+---------+------+------+-------------+
| table            | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+------------------+-------+---------------+---------+---------+------+------+-------------+
| mantis_bug_table | index | NULL          | PRIMARY |        4  | NULL |    30  | Using index |
+------------------+-------+---------------+---------+---------+------+------+-------------+
 1  row in set ( 0 . 00  sec)

mysql> EXPLAIN select id from bugs.mantis_bug_table ORDER BY rand() LIMIT  1 ;
+------------------+-------+---------------+---------+---------+------+------+----------------------------------------------+
| table            | type  | possible_keys | key     | key_len | ref  | rows | Extra                                        |
+------------------+-------+---------------+---------+---------+------+------+----------------------------------------------+
| mantis_bug_table | index | NULL          | PRIMARY |        4  | NULL |    30  | Using index; Using temporary; Using filesort |
+------------------+-------+---------------+---------+---------+------+------+----------------------------------------------+
 1  row in set ( 0 . 00  sec)
...
Рейтинг: 0 / 0
Выбор случайных фото
    #32875376
*
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
*
Гость
hellНо и в вашем случае будет происходить полное сканирование таблицы/индекса:А я и не утверждал обратного. Если внимательно вчитаться в ман, то будет понятно, что проблема в том, что функция RAND() - нешустрая. Собственно, возьмите базу поболе и посмотрите по времени, что будет быстрее select id from bugs.mantis_bug_table ORDER BY id LIMIT 5,1 или select id from bugs.mantis_bug_table ORDER BY rand() LIMIT 1
PS: подозреваю, что время выборки будет зависеть от номера записи, т.е. сгенерированного $rnd - попробуйте взять первую запись (LIMIT 0,1) и последнюю (LIMIT $max,1) и усреднить результат - у меня при единичных запросах (без учёта SELECT COUNT(*) FROM bugs.mantis_bug_table - MyAdmin не выдаёт время её выполнения - делать более правильный тест было лень) разница составила ~4 раза. Возможно, при выборе сразу нескольких записей, ситуация изменится (RAND() позволяет это сделать в один запрос). А вообще, попробуйте - из того же phpMyAdmin'а при многократных запросах типа select id from bugs.mantis_bug_table ORDER BY rand() результат мне показался неудовлетворительным.
...
Рейтинг: 0 / 0
Выбор случайных фото
    #32875386
*
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
*
Гость
В догонку - для RAND'а ещё и Using temporary и Using filesort
...
Рейтинг: 0 / 0
Выбор случайных фото
    #32875648
TigranE
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Люди, какие несколько сотен тысяч??! таблица у меня совсем крохотная - всего 200 записей в настоящее время, а самое большее ожидается около 1500, да и то не реально:)) В общем, сделал нижеописанным способом и вроде нормально работает... Какие будут замечания?

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
  $res=mysql_query('select distinct * from '.TBL_PHOTOS.
    ' group by good_id order by rand(unix_timestamp()) limit '.RAND_PHOTOS_NUM)
    or die(mysql_error());
  while($row=mysql_fetch_assoc($res))
  {
    extract($row);
    ...
  }
...
Рейтинг: 0 / 0
Выбор случайных фото
    #32875694
Фотография hell
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
group by good_id и distinct одновременно - скорее всего излишество, и выбирай не *, а те поля, которые конкретно нужно иметь



"The CBO without stats is like a morning without coffee." T.Kyte
...
Рейтинг: 0 / 0
Выбор случайных фото
    #32875883
*
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
*
Гость
TigranEВ общем, сделал нижеописанным способом и вроде нормально работает...Бред какой-то. Всё, что нужно, уже было написано - умный человек сделает из этого правильные выводы - глупый - пойдёт на поводу чужого мнения.
...
Рейтинг: 0 / 0
Выбор случайных фото
    #32877461
TigranE
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
* TigranEВ общем, сделал нижеописанным способом и вроде нормально работает...Бред какой-то. Всё, что нужно, уже было написано - умный человек сделает из этого правильные выводы - глупый - пойдёт на поводу чужого мнения.

No ved' vse otlichno rabotaet, generator sluchaynyx chisel vpolne ustraivaet, chto kasaetsya skorosti, to protestiroval sistemu s maximal'no vozmojnym chislom zapisej - zaderjka daje ne zametna..... nu pochemu bred?
...
Рейтинг: 0 / 0
Выбор случайных фото
    #32877839
1024byte
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я чего,то не понимаю?
нафиг вам этот лимит?
может проще сделать так :
$myquery = "select * from ".TBL_PHOTOS." where id = ".rand()." or id = ".rand()." or id=".rand().";"
...
Рейтинг: 0 / 0
Выбор случайных фото
    #32877876
sky2k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1024byteЯ чего,то не понимаю?
нафиг вам этот лимит?
может проще сделать так :
$myquery = "select * from ".TBL_PHOTOS." where id = ".rand()." or id = ".rand()." or id=".rand().";"

ггг
...
Рейтинг: 0 / 0
Выбор случайных фото
    #32877915
*
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
*
Гость
1024byte$myquery = "select * from ".TBL_PHOTOS." where id = ".rand()." or id = ".rand()." or id=".rand().";"Если вы такие умные, что ж вы строем не ходите? (С) народная мудрость.
и в результате не получить ниодной записи ;)
...
Рейтинг: 0 / 0
Выбор случайных фото
    #32877933
TigranE
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
1024byteЯ чего,то не понимаю?
нафиг вам этот лимит?
может проще сделать так :
$myquery = "select * from ".TBL_PHOTOS." where id = ".rand()." or id = ".rand()." or id=".rand().";"

nu et ty i vpravdu peregnul
...
Рейтинг: 0 / 0
34 сообщений из 34, показаны все 2 страниц
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / Выбор случайных фото
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]