У меня часто есть большие массивы или большие объемы динамических данных на PHP, которые мне нужны для запуска запросов MySQL.
Есть ли лучший способ запускать многие процессы, такие как INSERT или UPDATE, без обращения к информации, которая будет INSERT-ed или UPDATE-ed?
Пример (я не использовал подготовленный оператор для краткости):
$ myArray = array ('apple', 'orange', 'grape'); foreach ($ myArray как $ arrayFruit) { $ query = "INSERT INTO` Fruits` (`FruitName`) VALUES ('". $ arrayFruit. "')"; mysql_query ($ query, $ connection); }
ВАРИАНТ 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')";
Это, вероятно, так, как вы хотите.
Если у вас есть класс 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 }
одно замечание о вашем оригинальном решении по методу имплозии jerebear (которое я использовал раньше и любил) заключается в том, что его легче читать. Имплозия требует больше циклов мозгов программиста, чтобы понять, что может быть дороже, чем процессорные циклы. преждевременная оптимизация, бла, бла, бла … 🙂
Одна вещь, чтобы отметить ответ jerebear с несколькими VALUE-блоками в одном INSERT:
Это может быть довольно опасно для действительно больших объемов данных, поскольку большинство СУБД имеют верхний предел размера команд, которые они могут обрабатывать. Если вы превысите это со слишком большим количеством VALUE-блоков, ваша вставка не удастся. В MySQL, например, предел обычно составляет 1 МБ AFAIK.
Поэтому вы должны выяснить, какой максимальный размер (в идеале во время выполнения, может быть доступен из метаданных базы данных), и убедитесь, что вы не превышаете его, распространяя свои списки значений на несколько INSERT.
Я был вдохновлен ответом Джеребера на создание чего-то вроде его второго варианта для одного из моих текущих проектов. Из-за объема сдвига записей я не смог сохранить и сделать все данные сразу. Поэтому я построил это для импорта. Вы добавляете свои данные, а затем вызываете метод, когда каждая запись завершена. После определенного, настраиваемого количества записей данные в памяти будут сохранены с помощью массовой вставки, такой как второй вариант jerebear.
// 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();
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")...