Как оптимизировать код php/mysql?

388
24 февраля 2017, 03:27

Как можно оптимизировать код, представленный ниже?

$xml = simplexml_load_file("xmlfiles/".$row['idzk'].".xml"); 
foreach ($xml->offer as $offer) {
    $id= 'internal-id';
    $import_obj = mysql_query("SELECT `internal-id` FROM object WHERE `internal-id`='$offer[$id]' ");
    if(mysql_fetch_array($import_obj)){
        echo '1';
    }
    else {
        echo '2';
    }
}
Answer 1

Проблема вашего кода в том, что вы делаете N запросов в базу там, где можно обойтись одним.

$xml = simplexml_load_file("xmlfiles/".$row['idzk'].".xml"); 
$offers = iterator_to_array($xml->offer);
if (count($offers) == 0) die('No ids');
$ids = array_map(function($offer){
  //return (int)$offer['internal-id'];
  return "'".mysql_real_escape_string($offer['internal-id'])."'";
}, $offers);
$in = implode(', ', $ids);
$sql = "select `internal-id` from `object` where `internal-id` IN ($in)";
$r = mysql_query($sql);
if (!$r) die(mysql_error());
$exists = [];
while ($row = mysql_fetch_array($r, MYSQL_ASSOC)) {
  $exists[$row['internal-id']] = true;
}
foreach ($offers as $offer) {
  if (isset($exists[$offer['internal-id']])) {
    echo "Найден {$offer['internal-id']}\n";
  } else {
    echo "Не найден {$offer['internal-id']}\n";
  }
}

Если строк слишком много, можно отправлять пачками, скажем по 1000

Для задачи из комментариев можно создать уникальный индекс по полю internal-id и воспользоваться конструкцией on duplicate key update:

$offers = iterator_to_array($xml->offer);
$values = array_map(function($offer) {
  // нужно экранировать значения здесь по необходимости
  //return '('.implode(', ', [(int)$offer['internal-id'], (int)$offer['a']]).')';
  return '('.implode(',', [
    "'".mysql_real_escape_string($offer['internal-id'])."'",
    int($offer['a']),
  ]).')';
}, $offers);
$values = implode(",\n", $values);
$sql = <<<SQL
INSERT INTO `object` (`internal-key`, `a`) 
VALUES $values 
ON DUPLICATE KEY UPDATE 
  a = VALUES(a)
SQL;

mysql_

Внимание: Данное расширение устарело, начиная с версии PHP 5.5.0, и удалено в PHP 7.0.0. Используйте вместо него MySQLi или PDO_MySQL. Смотрите также инструкцию MySQL: выбор API и соответствующий FAQ для получения более подробной информации.

Answer 2

Оптимизировал (нет)

$load_file_name = "xmlfiles/".$row['idzk'].".xml";
$xml = simplexml_load_file($load_file_name);
foreach ($xml->offer as $offer) 
{
    $sql = "
    SELECT `internal-id`
    FROM `object`
    WHERE `internal-id`='{$offer['internal-id']}';
    ";
    $import_obj = mysql_query($sql);
    echo mysql_fetch_array($import_obj) ? "1" : "2";
}
READ ALSO
Асинхронные запросы PHP

Асинхронные запросы PHP

Подскажите как лучше организовать асинхронные запросы в PHP?

460
Есть ли кеширование запросов в IIS?

Есть ли кеширование запросов в IIS?

Можно ли IIS настроить так, чтобы, например, один и тот же запрос кешировался минут на 10 и пользователю возвращался сохраненный HTML вместо нового...

276
Опять сессии в CodeIgniter

Опять сессии в CodeIgniter

Реализовываю следующий модульДобавления товара в избранное

420