За последние 24 часа нас посетили 22773 программиста и 1203 робота. Сейчас ищут 683 программиста ...

случайная выборка

Тема в разделе "MySQL", создана пользователем bruto, 14 ноя 2006.

  1. bruto

    bruto Активный пользователь

    С нами с:
    18 сен 2006
    Сообщения:
    68
    Симпатии:
    0
    наткнулся случайно на похожую тему...
    Не подкинете хорошую идею, как из таблицы в миллион и более записей выбрать случайные 10? Буду очень благодарен!
    У меня есть несколько решений... но у всех есть заметные недостатки :о(
     
  2. svk

    svk Активный пользователь

    С нами с:
    7 авг 2006
    Сообщения:
    506
    Симпатии:
    0
    Адрес:
    NetByNet
    SELECT * FROM table ORDER BY RAND() LIMIT 10;
     
  3. bruto

    bruto Активный пользователь

    С нами с:
    18 сен 2006
    Сообщения:
    68
    Симпатии:
    0
    Я уже писал про этот метод в другой теме..

    .. значение rand не присутствует в таблице - соответственно перед сортировкой оно будет добавлено для каждой записи..
    а лимитом можно ограничить только кол-во выводимых записей, количество же записей которое выужден будет обработать сервак от этого не изменится..
     
  4. Mavir

    Mavir Guest

    bruto, сначало попробуй этот запрос
     
  5. svk

    svk Активный пользователь

    С нами с:
    7 авг 2006
    Сообщения:
    506
    Симпатии:
    0
    Адрес:
    NetByNet
    PHP:
    1. <?php
    2. $i=0;
    3. for ($i++; --$i<10; $i+=2)
    4. {
    5.    $sql = 'SELECT * FROM table WHERE id = '.rand(1000000);
    6.    $result = mysql_query($sql);
    7.    if(mysql_num_rows() == 0) { $i--; continue;}
    8.    $row = mysql_fetch_row($result);
    9.    $massiv[] = $row['pole'];
    10. }
    11. ?>
     
  6. bruto

    bruto Активный пользователь

    С нами с:
    18 сен 2006
    Сообщения:
    68
    Симпатии:
    0
    да.. Спасибо большое что не прошли стороной..))
    у меня в вообще то что то похожее...
    просто много уже полей уделено.. а будет еще больше..
    цикл может быть очень долгим :о(
     
  7. А можно поинтересоваться - для каких целей делается случайная выборка из миллиона записей?
     
  8. Hight

    Hight Старожил
    Команда форума Модератор

    С нами с:
    5 мар 2006
    Сообщения:
    7.153
    Симпатии:
    0
    Адрес:
    из злой параллельной вселенной
    лотерея - угадай десять чисел из миллиона =)
     
  9. bruto

    bruto Активный пользователь

    С нами с:
    18 сен 2006
    Сообщения:
    68
    Симпатии:
    0
    не-а.. ни каких лотерей!))
    просто информация
     
  10. офигенный ответ. "просто информация".
    А я-то думал - вода газированная.
     
  11. svk

    svk Активный пользователь

    С нами с:
    7 авг 2006
    Сообщения:
    506
    Симпатии:
    0
    Адрес:
    NetByNet
    у меня на одном портале работает такой код:
    PHP:
    1. <?php
    2.  
    3. for($i=0;$i<3;$i++)
    4. {
    5.         $sql = 'SELECT * FROM phpbb_games LIMIT '.rand(0, $all).', 1';
    6.         $result = $db->sql_query($sql);
    7.         $ranrow = $db->sql_fetchrow($result);
    8.  
    9.         $ranout .= "
    10.        <tr><td align='center'><a href = '/game.php?id=$ranrow[id]'><img border=0 src = '$pic_prefix$ranrow[image]' width=120 /></a></td></tr>
    11.        <tr><td align='center'><a href = '/game.php?id=$ranrow[id]'>$ranrow[game]</a></td></tr>";
    12. }
    13.  
    14. ?>
     
  12. Длинный лимит сильно тормозит.

    А вот если выбираются, скажем, анекдоты, и совсем не обязательно, чтобы они все шли в разнобой, то запрос можно очень упростить.
     
  13. Vah

    Vah Активный пользователь

    С нами с:
    15 май 2006
    Сообщения:
    228
    Симпатии:
    0
    Можно что нить в этом роде подюзать:
    PHP:
    1.  
    2. <?
    3.     define("K",2);
    4.     $limit=10;
    5.    
    6.     function get_n_random_nums($n, $min, $max){
    7.         for($i=0; $i<$n; $i++) $nums[]=round(rand($min,$max));
    8.         return $nums;
    9.     }
    10.    
    11.     $sql="select min(id) as minid, max(id)as maxid, ".K." * (count(id) / (max(id) - min(id))) as num_of_rand FROM table";
    12.     $r=mysql_query($sql);
    13.     if($r){
    14.         $row=mysql_fetch_assoc($r);
    15.         $newlimit=ceil($row["num_of_rand"]*$limit);
    16.         $rn=array();
    17.         while(1){
    18.             $rn=array_merge($rn, get_n_random_nums($newlimit, $row["minid"], $row["maxid"]));
    19.             $rn=array_unique($rn);
    20.             $in_ids=implode(",",$rn);
    21.             $sql="SELECT * FROM table WHERE id IN (".$in_ids.")";
    22.             $r=mysql_query($sql);
    23.             if(mysql_num_rows()>=10) break;
    24.         }
    25.        
    26.         while($row=mysql_fetch_assoc($r)){
    27.             // Делаем что-то с полученными данными
    28.         }
    29.     }else{
    30.         mysql_error($link);
    31.     }
    32.  
    33. ?>
    34.  
    Можно думаю подшлейфовать кое-где.... Но это Вы уж сами..... Не оставлять же вас без работы совсем...... ;)
     
  14. Vah

    Vah Активный пользователь

    С нами с:
    15 май 2006
    Сообщения:
    228
    Симпатии:
    0
    Да, и это случаем не эта тема:
    ???
     
  15. Vah
    а твой код делает не то же самое, что и предыдущий код svk, который короче раза в два?
     
  16. Vah

    Vah Активный пользователь

    С нами с:
    15 май 2006
    Сообщения:
    228
    Симпатии:
    0
    Чебурген
    а ты перечитай, протестируй на табличке в миллион записей и отпиши рез-тат....

    Тем более здесь я скорее открываю глаза на алгоритм..... Код этот можно и даже нужно ещё корректировать....
     
  17. перечитал.
    так и не увидел принципиальных отличий от, я повторюсь - предыдущего кода svk. Если не считать косяков, которые надо "подшлейфовать".
     
  18. Vah

    Vah Активный пользователь

    С нами с:
    15 май 2006
    Сообщения:
    228
    Симпатии:
    0
    Чебурген
    Перечитай ещё раз, проанализируй.... Пойми как работает его вар-т и мой, протестируй на табличке в миллион значений с дырками в столбце id...... И отпиши потом рез-тат....
    Может отшлейфуешь заодно код......

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

    А тестировать ни один из предложенных здесь вариантов я не собираюсь. поскольку все они кривые. просто исходя из самой постановки задачи.
    Если передо мной встанет подобная задача, буду решать её не "в лоб", а с умом.
     
  20. Vah

    Vah Активный пользователь

    С нами с:
    15 май 2006
    Сообщения:
    228
    Симпатии:
    0
    Чебурген
    ну вот задача..... реши с умом..... мы не умеем.... нас в школе научили только в лоб решать.....

    Кусок кода в студию.... берем таблицу >=1000000 рядов
     
  21. Никакой задачи я здесь не вижу.
    А только высосанный из пальца пример.
    Ты, наверное, не понял. Речь идёт о реальной задаче.
     
  22. Vah

    Vah Активный пользователь

    С нами с:
    15 май 2006
    Сообщения:
    228
    Симпатии:
    0
    Чебурген
    Ну покажи нам как надо решать реальные задачи..... Мы умеем только примеры из пальца высасывать.....
     
  23. Давайте вашу задачу! =)
     
  24. Vah

    Vah Активный пользователь

    С нами с:
    15 май 2006
    Сообщения:
    228
    Симпатии:
    0
  25. Это всё не реальная задача.
    А уже готовые решения.

    Я тебе поясню разницу.
    Реальная задача - пойти в гости в чистых носках.
    Решение - постирать. Причём в отсутствие воды. Если хочешь - ломай голову над этим готовым решением.
    А я пойду, и куплю носки в магазине.

    Понятно, что я имею в виду?
    Я не представляю себе реальную задачу, при которой надо выбирать 10 случайных идущих вразнобой записей обязательно из всего миллиона.
    И жду, что ты мне напишешь реальную задачу, в которой может понадобиться что-то подобное.
    И я тебе моментально дам решение, при котором выборка из миллиона не понадобится.