[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Увеличить скорость запроса
Spydel
Привет всем! Прошу Вас помочь мне! Я столкнулся с такой задачей:
Мне нужно из текстового файла построчно считывать инфу и записывать в базу, но если такая инфа уже есть, то ее обновлять. Я все сделал и все работает, но быстро работает когда первый раз прогоняется выгрузка в базу, так как идет INSERT, а вот когда записей около 30 тясяч, т.е. запуск 2-ой раз, то все работает медлено (ОЧЕНЬ). Подскажите пожалуйста как рациональнее подойти к этой задаче?

Вот код:
<?php
$f_arr = file( "/unload/structure.txt" );

$i = 0;


while ($i<count($f_arr)) {

$arr = explode(";", $f_arr[$i]);

$arr[1] = translit($arr[1]);
$arr[2] = translit($arr[2]);

$nm = mysql_query("SELECT * FROM engine_options_com_shop WHERE id = '".$arr[1]."' ");


if (mysql_num_rows($nm) == 0 ) {

mysql_query("INSERT INTO engine_options_com_shop (id, catid, name, is_type, seo_name,view_stat) VALUES ('".$arr[1]."', '".$arr[2]."', '".$arr[3]."', 'cat','".$arr[1]."','".$del."')");

} else {

if ($arr[0] == '-') {

mysql_query("UPDATE engine_options_com_shop SET view_stat = '0' WHERE id = '" . $arr[1] . "'");

}

}


$i++;

}


?>




Спустя 10 минут, 18 секунд (18.12.2010 - 00:08) inpost написал(а):
Первое: уменьшаем нагрузку при выборке:
SELECT `id`. - теперь запрос в 2,5 раза быстрее, чем выборка всех полей.
А вот второе, можно сделать одним запросом, но не знаю, потянет ли мускул массовые вставки одним запросом.
$insertarray[] = "(VALUES)";
$insert = implode(",",$insertarray);
$res = mysql_query("INSERT INTO `". IRB_DBPREFIX ."gift`
(`man_id`,`girl_id`,`title`,`howmuch`,`comment`,`whosend`)
VALUES "
.$insert
);

Спустя 16 минут, 25 секунд (18.12.2010 - 00:25) silius написал(а):
inpost
наговорил человеку чушь, скопипастил с Ирбиса, а функции переименовать забыл? ;)

Я бы сделал бы так: считал файл file(); , выборку с базы перед циклом, сравнил бы массивы на одинаковые значения, если есть, выкинуть, сформировал бы запрос так:

$query = "('$arr[1]', '$arr[2]', '$arr[3]', 'cat', '$arr[1]', '$del'), ('$arr[1]', '$arr[2]', '$arr[3]', 'cat', '$arr[1]', '$del')";
а потом бы уже делал запрос к БД на вставку:

$sqlquery = "INSERT INTO engine_options_com_shop (id, catid, name, is_type, seo_name,view_stat) VALUES $query";
$result = mysql_query($sqlquery);

а таблицы в базе и файл большие? И ещё вопрос: этот процесс единоразовый либо постоянный?

Спустя 3 минуты, 58 секунд (18.12.2010 - 00:29) inpost написал(а):
silius
Да, код из ирбиса и мой =)
Ты показал тоже самое, что я сделал выше

Вот то, что ты показал в $query, у меня было заменено на VALUES.

Спустя 6 минут, 41 секунда (18.12.2010 - 00:36) silius написал(а):
inpost
просто Spydel возможно ниразу не заходил на ирбис, и не знает, что это: mysqlQuery. Хоть бы написал или ссылку дал. Я просто раньше тоже не понял сразу что это и к чему wink.gif

Спустя 1 минута, 54 секунды (18.12.2010 - 00:37) Guest написал(а):
Цитата (silius @ 17.12.2010 - 21:25)
inpost
наговорил человеку чушь, скопипастил с Ирбиса, а функции переименовать забыл? ;)

Я бы сделал бы так: считал файл file(); , выборку с базы перед циклом, сравнил бы массивы на одинаковые значения, если есть, выкинуть, сформировал бы запрос так:

$query = "('$arr[1]', '$arr[2]', '$arr[3]', 'cat', '$arr[1]', '$del'), ('$arr[1]', '$arr[2]', '$arr[3]', 'cat', '$arr[1]', '$del')";
а потом бы уже делал запрос к БД на вставку:

$sqlquery = "INSERT INTO engine_options_com_shop (id, catid, name, is_type, seo_name,view_stat) VALUES $query";
$result = mysql_query($sqlquery);

а таблицы в базе и файл большие? И ещё вопрос: этот процесс единоразовый либо постоянный?

Файл весит 1.5 mb потом может больше
Процесс каждый 2 часа будет запускаться.

А как мне сделать выборку перед циклом не зная текущего значения, мне ведь все равно придется в цикле запрос делать? Так?

Спустя 2 минуты, 27 секунд (18.12.2010 - 00:40) inpost написал(а):
В цикле формируешь лишь $insertarray. За пределами цикла, когда он уже закончился, выполняешь вставку. Код я дал выше, читай, разбирайся, подставляй свои поля вместо моих.
$insert = implode(",",$insertarray);
$res = mysql_query("INSERT INTO `". IRB_DBPREFIX ."gift`
(`man_id`,`girl_id`,`title`,`howmuch`,`comment`,`whosend`)
VALUES "
.$insert
);
[/php]

Спустя 3 минуты, 35 секунд (18.12.2010 - 00:43) Spydel написал(а):
Цитата (inpost @ 17.12.2010 - 21:40)
В цикле формируешь лишь $insertarray. За пределами цикла, когда он уже закончился, выполняешь вставку. Код я дал выше, читай, разбирайся, подставляй свои поля вместо моих.
$insert = implode(",",$insertarray);
$res = mysql_query("INSERT INTO `". IRB_DBPREFIX ."gift`
(`man_id`,`girl_id`,`title`,`howmuch`,`comment`,`whosend`)
VALUES "
.$insert
);
[/php]

Да дело в том, что вставка работает быстро, но Проверка сам Select медлено!! Вот проблема как мне проверить есть ли такая запись в базе.

Спустя 38 минут, 31 секунда (18.12.2010 - 01:22) inpost написал(а):
Я выше написал, проверяй конкретно на SELECT `id` , а не SELECT *

Спустя 3 часа, 25 минут, 57 секунд (18.12.2010 - 04:48) kirik написал(а):
Цитата (Spydel @ 17.12.2010 - 16:43)
Да дело в том, что вставка работает быстро, но Проверка сам Select медлено!!

Используйте INSERT ... ON DUPLICATE KEY UPDATE .... Будет всего один запрос вместо ваших трёх.

Спустя 7 часов, 58 минут, 29 секунд (18.12.2010 - 12:46) Spydel написал(а):
Цитата (kirik @ 18.12.2010 - 01:48)
Цитата (Spydel @ 17.12.2010 - 16:43)
Да дело в том, что вставка работает быстро, но Проверка сам Select медлено!!

Используйте INSERT ... ON DUPLICATE KEY UPDATE .... Будет всего один запрос вместо ваших трёх.

kirik, спасибо тебе огромное! Помогло и работает быстро!!! smile.gif
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.