За последние 24 часа нас посетили 16557 программистов и 1559 роботов. Сейчас ищут 2018 программистов ...

Помогите запро+цикл+запись+mysql

Тема в разделе "PHP и базы данных", создана пользователем CJlE3bl, 7 ноя 2008.

  1. CJlE3bl

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

    С нами с:
    7 ноя 2008
    Сообщения:
    5
    Симпатии:
    0
    PHP:
    1. $w0="SELECT * FROM people WHERE race = 'man'";
    2. $result = mysql_query($w0);
    3. for($i=1;$i<=$num;$i++) {
    4.   if ($i) {
    5.     $w01="SELECT * FROM people ORDER BY RAND() LIMIT 1";
    6.     $result1 = mysql_query($w01);
    7.     $f2 = mysql_fetch_array($result);
    8.     $id_f2 = $f2['id'];
    9.     $f = mysql_fetch_array($result1);
    10.     $id = $f['id'];
    11.     $w0_friend="INSERT INTO friends (id_name,id_friends) VALUES ('$id_f2','$id')";
    12.     mysql_query($w0_friend) or mysql_error();
    13.   }
    14. }
    Суть такова что у меня в Бд $num превышает 50 тысяч записей. При запуске цикла, всё обработка происходит мега долго.
    Помогите облегчить код с учётом того, что записи могут достигать свыше 1 миллиона.
     
  2. немудрено....
     
  3. CJlE3bl

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

    С нами с:
    7 ноя 2008
    Сообщения:
    5
    Симпатии:
    0
    Как это всё облегчить?
     
  4. Luge

    Luge Старожил

    С нами с:
    2 фев 2007
    Сообщения:
    4.680
    Симпатии:
    1
    Адрес:
    Минск
  5. CJlE3bl

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

    С нами с:
    7 ноя 2008
    Сообщения:
    5
    Симпатии:
    0
    С этим понятно, но, а как же цикл, перебирать от 1 до 50 тысяч, долго же. Это как минимум, планируется до 1 миллиона.
     
  6. obsrv

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

    С нами с:
    2 окт 2008
    Сообщения:
    238
    Симпатии:
    0
    Адрес:
    Санкт-Петербург
    Не с потолка рекомендую:
    1. делать выборку по id (там у вас все равно индекс) в $a (array).
    2. $res = array_rand($a, count($a));
    3. делать дальше что хочется.

    присмотрелся к задаче (если правильно понял).
    если записать абстрактно:
    Код (Text):
    1.  
    2.   $men = "SELECT id FROM people WHERE race = 'man'";
    3.   $other = "SELECT id FROM people";
    4.   foreach ($men as $man) {
    5.     INSERT INTO .....  array_rand($other) ... ;
    6.   }
    ps: кстати, тут тоже можно улучшить по производительности. hint (я пока в guide не смотрел но думаю аналогично IN): копать в сторону максимального количества указаний в INSERT для VALUES - в смысле сколько за раз пар вставить. Соответственно одним селектом вычисляем этот буфер. Запихиваем туда из цикла значения, при заполнении вызываем один INSERT запрос и тд.
     
  7. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    В цикле лучше не делать запросов.
     
  8. obsrv

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

    С нами с:
    2 окт 2008
    Сообщения:
    238
    Симпатии:
    0
    Адрес:
    Санкт-Петербург
    Kreker
    Это верно для всех реляционных бд.
    Но в поставленной задаче (есть такие в природе) все-таки от INSERT не уйти, я предложил оптимизацию для INSERT тоже.

    + можно сгрузить все в файлО и сделать один запрос: "LOAD DATA INFILE ...", тогда можно и инсерт из кода снести.
     
  9. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    А для чего вообще тут нужен рэндом, что-то я не догоняю.
     
  10. CJlE3bl

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

    С нами с:
    7 ноя 2008
    Сообщения:
    5
    Симпатии:
    0
    У меня тут небольшая система и очень часто надо выводить рандомные записи. Из-за чего загрузка системы большая, если в запросе использовать "ORDER BY RAND() LIMIT 1"
     
  11. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    Потому что RAND работает медленно. Если тебе известно количество записей в таблице, хотя-бы примерно - генерируй случайное число с помощью PHP и выбирай селектом запись с таким ID.
     
  12. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    Сначала SELECT `id` в mySQL, потом mt_rand в PHP, после подставляем Id в SELECT-запрос IN (...).
    Возвращаемый результат обрабатываем в цикле, собирая для запроса (...). В конце один запрос INSERT INTO ... VALUES (...), (...), (...), (...)
    Правда надо следить, чтобы данных было не так много, ибо Mysql все не примет и придется разбивать запрос на несколько.
     
  13. obsrv

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

    С нами с:
    2 окт 2008
    Сообщения:
    238
    Симпатии:
    0
    Адрес:
    Санкт-Петербург
    Kreker
    вот собственно даже ухудшили МОЙ вариант :(

    CJlE3bl
    делайте, как я написал. Пройденный этап.
     
  14. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    obsrv
    Извиняюсь, неправильно принял пост. Я посмотрел сразу на код и увидел, что там в цикле запросы, поэтому и написал свой вариант
     
  15. CJlE3bl

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

    С нами с:
    7 ноя 2008
    Сообщения:
    5
    Симпатии:
    0
    Всем спасибо, проблему решил с вашей помощью.