Разве плохо помещать MySQL-запрос в цикл PHP? - PullRequest
10 голосов
/ 09 апреля 2009

У меня часто есть большие массивы или большие объемы динамических данных в PHP, которые мне нужны для выполнения запросов MySQL.

Есть ли лучший способ запустить многие процессы, такие как INSERT или UPDATE, не просматривая информацию для ввода INSERT или UPDATE-ed?

Пример (я не использовал подготовленное заявление для краткости):

$myArray = array('apple','orange','grape');

foreach($myArray as $arrayFruit) {
$query = "INSERT INTO `Fruits` (`FruitName`) VALUES ('" . $arrayFruit . "')";
mysql_query($query, $connection);
}

Ответы [ 6 ]

20 голосов
/ 09 апреля 2009

ВАРИАНТ 1 Вы можете одновременно запускать несколько запросов.

$queries = '';

foreach(){
    $queries  .= "INSERT....;";  //notice the semi colon
}

mysql_query($queries, $connection);

Это сэкономит на вашей обработке.

ВАРИАНТ 2

Если ваша вставка настолько проста для одной таблицы, вы можете выполнить несколько вставок в ОДНОМ запросе

$fruits = "('".implode("'), ('", $fruitsArray)."')";
mysql_query("INSERT INTO Fruits (Fruit) VALUES $fruits", $connection);

Запрос выглядит примерно так:

$query = "INSERT INTO Fruits (Fruit)
  VALUES
  ('Apple'),
  ('Pear'),
  ('Banana')";

Это, вероятно, путь, которым вы хотите идти.

5 голосов
/ 09 апреля 2009

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

$sth = $dbh->prepare("INSERT INTO Fruits (Fruit) VALUES (?)");
foreach($fruits as $fruit)
{
    $sth->reset(); // make sure we are fresh from the previous iteration
    $sth->bind_param('s', $fruit); // bind one or more variables to the query
    $sth->execute(); // execute the query
}
3 голосов
/ 09 апреля 2009

Одна вещь, которую следует отметить относительно вашего первоначального решения по поводу метода взрыва jerebear (который я использовал ранее и люблю), состоит в том, что его легче читать. Имплозия требует больше мозгов программиста, чтобы понять, что может быть дороже, чем процессорные циклы. преждевременная оптимизация, бла, бла, бла ...:)

2 голосов
/ 12 апреля 2009

Стоит отметить, что ответ Джеребира с несколькими VALUE-блоками в одном INSERT:

Это может быть довольно опасно для действительно больших объемов данных, поскольку большинство СУБД имеют верхний предел размера команд, которые они могут обрабатывать. Если вы превысите это со слишком большим количеством VALUE-блоков, ваша вставка не удастся. Например, в MySQL ограничение обычно составляет 1 МБ AFAIK.

Таким образом, вы должны выяснить, какой максимальный размер (в идеале во время выполнения, может быть доступен из метаданных базы данных), и убедитесь, что вы не превышаете его, распределяя списки значений по нескольким INSERT.

0 голосов
/ 13 марта 2014
foreach ($userList as $user) {
$query = 'INSERT INTO users (first_name,last_name)  VALUES("'.$user['first_name'].'",        "' . $user['last_name'] . '")';
mysql_query($query);

}

Insted Используя вышеописанное, попробуйте следующее. Вместо использования цикла вы можете объединить данные в один запрос к базе данных.

$userData = array();
foreach ($userList as $user) {
$userData[] = '("' . $user['first_name'] . '", "' . $user['last_name'] . '")';
}
$query = 'INSERT INTO users (first_name,last_name) VALUES' . implode(',', $userData);
mysql_query($query);

Produces:

INSERT INTO users (first_name,last_name) VALUES("John", "Doe"),("Jane", "Doe")...
0 голосов
/ 12 апреля 2009

Меня вдохновил ответ Джеребира на создание чего-то вроде его второго варианта для одного из моих текущих проектов. Из-за большого количества записей я не смог сохранить и сделать все данные одновременно. Поэтому я построил это для импорта. Вы добавляете свои данные, а затем вызываете метод, когда каждая запись сделана. После определенного настраиваемого количества записей данные в памяти будут сохранены с массовой вставкой, как вторая опция Джеребира.

// CREATE TABLE example ( Id INT, Field1 INT, Field2 INT, Field3 INT);
$import=new DataImport($dbh, 'example', 'Id, Field1, Field2, Field3');
foreach ($whatever as $row) {
  // add data in the order of your column definition
  $import->addValue($Id);
  $import->addValue($Field1);
  $import->addValue($Field2);
  $import->addValue($Field3);
  $import->nextRow();
}
$import->lastRow();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...