Оптимизировать алго в плане запросов к БД

Тема в разделе "PHP", создана пользователем phillip, 9 сен 2010.

Статус темы:
Закрыта.
Модераторы: latteo
  1. phillip

    phillip

    Регистр.:
    4 сен 2007
    Сообщения:
    413
    Симпатии:
    15
    Есть страница которая каждую секунду отдает 20 новых кеев. Я эту страницу решил парсить и кеи собирать в БД. При этом, если такой кей в бд уже есть, то мы не записываем его вновь, а добавляем +1 к к нему. То есть получается два поля
    кей | сколько раз встретился

    Я сделал алгоритм самый простейщий-
    PHP:
    foreach($parsed_keys as $key){
    $query "SELECT * FROM `parse_keys` WHERE `key`='".$key."'";
    if(
    mysql_num_rows($result)==0){
                
    $query "INSERT INTO `parse_keys` VALUES('0','1','".addslashes($key)."')";
                
    mysql_query($query,$link) or die(mysql_error()."<br />\n".$query);
            } else {
                
    $row=mysql_fetch_assoc($result);
                
    $row['rc']++;
                echo 
    'update <b>'.$row['key'].'</b> set rc='.$row['rc'].'<br/>';
                
    $query "UPDATE `parse_keys` SET `rc`='".$row['rc']."' WHERE `key`='".addslashes($row['key'])."'";
                
    mysql_query($query,$link) or die(mysql_error()."<br />\n".$query);
            }
            
    }
    Дак вот такой алгоритм выполняется каждую секунду. или в секунду дважды даже. В итоге через три дня работы я не смог попасть в мускуль- too many connections
    Вопрос- как лучше оптимизировать алгоритм в плане запросов к БД
     
  2. jo0o00nyy

    jo0o00nyy Постоялец

    Регистр.:
    12 май 2010
    Сообщения:
    65
    Симпатии:
    27
    как вариант по быстрому... уникальный индекс на "key" + следующее
    Код:
    foreach($parsed_keys as $key){
        $query = "INSERT INTO `parse_keys` VALUES('0','1','".addslashes($key)."')";
        $query .= " ON DUPLICATE KEY UPDATE rc=rc+1";
        mysql_query($query,$link) or die(mysql_error()."<br />\n".$query);
    }
    
     
    zss и phillip нравится это.
  3. phillip

    phillip

    Регистр.:
    4 сен 2007
    Сообщения:
    413
    Симпатии:
    15
    а можно сделать как-то чтобы без foreach а то получается все равно 20 запросов к бд в секунду. Может можно как-то сделать один, но большой запрос
     
  4. chang

    chang

    Регистр.:
    20 ноя 2009
    Сообщения:
    363
    Симпатии:
    117
    попробуй так
    но уточни размер разрешенного SQL выражения для СУБД ... а то если $parsed_keys достаточно большой то запрос вылетит
    PHP:
    $query "INSERT INTO `parse_keys` VALUES ";
    foreach(
    $parsed_keys as $key
        
    $query .=    "('0','1','".addslashes($key)."'),";
    $query =  substr($query0, -1);
    $query .= " ON DUPLICATE KEY UPDATE rc=rc+1"
       
    mysql_query($query,$link) or die(mysql_error()."<br />\n".$query);
     
    phillip нравится это.
  5. phillip

    phillip

    Регистр.:
    4 сен 2007
    Сообщения:
    413
    Симпатии:
    15
    Спасибо! я вот думаю может сделать так что записываем это все в текстовик temp_base.txt и раз в час собираем оттуда все, и записываем в БД. Получается текстовик разрастаться не будет, раз в час будет опустошаться, и запросы к бд не часто.
    как лучше? А то вдруг у меня мускуль падать будет, а это уже случалось
     
  6. t3s

    t3s

    Регистр.:
    16 фев 2008
    Сообщения:
    719
    Симпатии:
    290
    это называется кешированием
     
  7. phillip

    phillip

    Регистр.:
    4 сен 2007
    Сообщения:
    413
    Симпатии:
    15
    да, а как лучше все-таки поступить?
     
  8. venetu

    venetu

    Регистр.:
    28 мар 2007
    Сообщения:
    737
    Симпатии:
    263
    Лучше всего как chang советует. Если так будет работать - это самый идеальный вариант. Но мне кажется что работать не будет.

    Если нет - разнеси задачу на два разных скрипта - один пусть собирает ключи, второй время от времени скидывает накопленное в базу.
     
  9. Kloster

    Kloster

    Регистр.:
    22 июн 2009
    Сообщения:
    216
    Симпатии:
    12
    Да, вариант с кешированием попробуй. Тут еще вопрос в специфике, как чато у тебя добавляются новые ключи? Если их большинство, то можно будет из того кеша текстового сформировать один запрос на инсерт, в котором блоками прописать все ключи новые. А вот для апдейта понадобятся разные запросы, хотя их тоже можно сгруппировать по размеру инкремента. Но все надо тестировать.
     
  10. sublimity

    sublimity Создатель

    Регистр.:
    7 янв 2008
    Сообщения:
    23
    Симпатии:
    3
    для себя список последних поисков по сайту (кев) сделал так ,есть небольшой сайтик 200 онлайн 50% через поиск по каталогу в 40000 позицый, т.е. db нельзя трогать ни прикаких.
    хотя с innodb plugin можно и сразу в бд :)

    использую memcache (xcache, eaccel... apc)
    PHP:
    $array=xcache_get("skeys"); //apc_fetch(...)
    @$array[$searchKey]++;
    if (
    sizeof($array)>2000)
    {
     
    file_put_content("zzzz.aaaa",implode("\n",$array),file_append);
    $array=array();
    }
    xcache_set("skeys",$array);
    Меня не интересовали потери нескольких кеев, и не интересовал потом разбор....
    но идея с кешем рулит...
     
Статус темы:
Закрыта.