Каков наилучший способ вставки нескольких строк в PHP PDO MYSQL?

Скажем, у нас есть несколько строк, которые нужно вставить в таблицу:

$rows = [(1,2,3), (4,5,6), (7,8,9) ... ] //[ array of values ]; 

Использование PDO:

 $sql = "insert into `table_name` (col1, col2, col3) values (?, ?, ?)" ; 

Теперь, как вы должны вставлять строки? Как это?

 $stmt = $db->prepare($sql); foreach($rows as $row){ $stmt->execute($row); } 

или, как это?

 $sql = "insert into `table_name` (col1, col2, col3) values "; $sql .= //not sure the best way to concatenate all the values, use implode? $db->prepare($sql)->execute(); 

Какой путь будет быстрее и безопаснее? Каков наилучший способ вставки нескольких строк?

У вас есть по крайней мере эти два варианта:

 $rows = [(1,2,3), (4,5,6), (7,8,9) ... ]; $sql = "insert into `table_name` (col1, col2, col3) values (?,?,?)"; $stmt = $db->prepare($sql); foreach($rows as $row) { $stmt->execute($row); } OR: $rows = [(1,2,3), (4,5,6), (7,8,9) ... ]; $sql = "insert into `table_name` (col1, col2, col3) values "; $paramArray = array(); $sqlArray = array(); foreach($rows as $row) { $sqlArray[] = '(' . implode(',', array_fill(0, count($row), '?')) . ')'; foreach($row as $element) { $paramArray[] = $element; } } // $sqlArray will look like: ["(?,?,?)", "(?,?,?)", ... ] // Your $paramArray will basically be a flattened version of $rows. $sql .= implode(',', $sqlArray); $stmt = $db->prepare($sql); $stmt->execute($paramArray); 

Как вы видите, первая версия имеет гораздо более простой код; однако вторая версия выполняет пакетную вставку. Вставка пакета должна быть быстрее, но я согласен с @BillKarwin, что разница производительности не будет замечена в подавляющем большинстве реализаций.

Я сделал бы это первым способом, подготовил оператор с одной строкой замещающих параметров и вставлял бы одну строку за раз с выполнением.

 $stmt = $db->prepare($sql); foreach($rows as $row){ $stmt-> execute($row); } 

Это не так быстро, как выполнение нескольких строк в одной вставке, но это достаточно близко, что вы, вероятно, никогда не заметите разницы.

И это имеет то преимущество, что с кодом очень легко работать. Вот почему вы все равно используете PHP, для эффективности разработчика, а не для производительности во время выполнения.

Если у вас много строк (сотни или тысячи), а производительность – приоритет, вам следует рассмотреть возможность использования LOAD DATA INFILE .

Вы также можете пойти так:

 <?php $qmarks = '(?,?,?)'. str_repeat(',(?,?,?)', count($rows)-1); $sql = "INSERT INTO `table`(col1,col2,col3) VALUES $qmarks"; $vals = array(); foreach($rows as $row) $vals = array_merge($vals, $row); $db->prepare($sql)->execute($vals); 

Честно говоря, я не знаю, какой из них будет быстрее, все зависит от задержки между mysql и php-сервером.

 /* test.php */ <?php require_once('Database.php'); $obj = new Database(); $table = "test"; $rows = array( array( 'name' => 'balasubramani', 'status' => 1 ), array( 'name' => 'balakumar', 'status' => 1 ), array( 'name' => 'mani', 'status' => 1 ) ); var_dump($obj->insertMultiple($table,$rows)); ?> /* Database.php */ <?php class Database { /* Initializing Database Information */ var $host = 'localhost'; var $user = 'root'; var $pass = ''; var $database = "database"; var $dbh; /* Connecting Datbase */ public function __construct(){ try { $this->dbh = new PDO('mysql:host='.$this->host.';dbname='.$this->database.'', $this->user, $this->pass); //print "Connected Successfully"; } catch (PDOException $e) { print "Error!: " . $e->getMessage() . "<br/>"; die(); } } /* Insert Multiple Rows in a table */ public function insertMultiple($table,$rows){ $this->dbh->beginTransaction(); // also helps speed up your inserts. $insert_values = array(); foreach($rows as $d){ $question_marks[] = '(' . $this->placeholders('?', sizeof($d)) . ')'; $insert_values = array_merge($insert_values, array_values($d)); $datafields = array_keys($d); } $sql = "INSERT INTO $table (" . implode(",", $datafields ) . ") VALUES " . implode(',', $question_marks); $stmt = $this->dbh->prepare ($sql); try { $stmt->execute($insert_values); } catch (PDOException $e){ echo $e->getMessage(); } return $this->dbh->commit(); } /* placeholders for prepared statements like (?,?,?) */ function placeholders($text, $count=0, $separator=","){ $result = array(); if($count > 0){ for($x=0; $x<$count; $x++){ $result[] = $text; } } return implode($separator, $result); } } ?> 

Вышеприведенный код должен быть хорошим решением для вставки нескольких записей с использованием PDO.