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

Статус
В этой теме нельзя размещать новые ответы.

phillip

Полезный
Регистрация
4 Сен 2007
Сообщения
411
Реакции
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
Вопрос- как лучше оптимизировать алгоритм в плане запросов к БД
 
как вариант по быстрому... уникальный индекс на "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);
}
 
а можно сделать как-то чтобы без foreach а то получается все равно 20 запросов к бд в секунду. Может можно как-то сделать один, но большой запрос
 
попробуй так
но уточни размер разрешенного SQL выражения для СУБД ... а то если $parsed_keys достаточно большой то запрос вылетит
PHP:
$query = "INSERT INTO `parse_keys` VALUES ";
foreach($parsed_keys as $key) 
    $query .=    "('0','1','".addslashes($key)."'),";
$query =  substr($query, 0, -1);
$query .= " ON DUPLICATE KEY UPDATE rc=rc+1"; 
   mysql_query($query,$link) or die(mysql_error()."<br />\n".$query);
 
Спасибо! я вот думаю может сделать так что записываем это все в текстовик temp_base.txt и раз в час собираем оттуда все, и записываем в БД. Получается текстовик разрастаться не будет, раз в час будет опустошаться, и запросы к бд не часто.
как лучше? А то вдруг у меня мускуль падать будет, а это уже случалось
 
это называется кешированием
 
да, а как лучше все-таки поступить?
 
Лучше всего как chang советует. Если так будет работать - это самый идеальный вариант. Но мне кажется что работать не будет.

Если нет - разнеси задачу на два разных скрипта - один пусть собирает ключи, второй время от времени скидывает накопленное в базу.
 
Да, вариант с кешированием попробуй. Тут еще вопрос в специфике, как чато у тебя добавляются новые ключи? Если их большинство, то можно будет из того кеша текстового сформировать один запрос на инсерт, в котором блоками прописать все ключи новые. А вот для апдейта понадобятся разные запросы, хотя их тоже можно сгруппировать по размеру инкремента. Но все надо тестировать.
 
для себя список последних поисков по сайту (кев) сделал так ,есть небольшой сайтик 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);

Меня не интересовали потери нескольких кеев, и не интересовал потом разбор....
но идея с кешем рулит...
 
Статус
В этой теме нельзя размещать новые ответы.
Назад
Сверху