Ich übergebe einen großen Datensatz über PHP mit Einfügebefehlen an eine MySQL-Tabelle und frage mich, ob es möglich ist, ungefähr 1000 Zeilen gleichzeitig über eine andere Abfrage einzufügen, als jeden Wert an das Ende einer kilometerlangen Zeichenfolge anzuhängen und dann ausführen. Ich verwende das CodeIgniter-Framework, daher stehen mir dessen Funktionen ebenfalls zur Verfügung.
Wie füge ich mehrere Zeilen aus einem Array mit dem CodeIgniter-Framework ein?
zu weit seitwärts
Statiksan
Einen zusammenbauen INSERT
-Anweisung mit mehreren Zeilen ist in MySQL viel schneller als eine INSERT
Anweisung pro Zeile.
Das heißt, es hört sich so an, als ob Sie in PHP auf Probleme mit der String-Verarbeitung stoßen könnten, was wirklich ein Algorithmusproblem ist, kein Sprachproblem. Wenn Sie mit großen Zeichenfolgen arbeiten, möchten Sie im Grunde unnötiges Kopieren minimieren. In erster Linie bedeutet dies, dass Sie eine Verkettung vermeiden möchten. Die schnellste und speichereffizienteste Methode zum Erstellen einer großen Zeichenfolge, z. B. zum Einfügen von Hunderten von Zeilen auf einmal, besteht darin, die Vorteile von zu nutzen implode()
Funktion und Array-Zuweisung.
$sql = array();
foreach( $data as $row ) {
$sql[] = '("'.mysql_real_escape_string($row['text']).'", '.$row['category_id'].')';
}
mysql_query('INSERT INTO table (text, category) VALUES '.implode(',', $sql));
Der Vorteil dieses Ansatzes besteht darin, dass Sie die SQL-Anweisung, die Sie bisher zusammengestellt haben, nicht bei jeder Verkettung kopieren und erneut kopieren müssen. Stattdessen übernimmt PHP dies Einmal in dem implode()
Aussage. Das ist ein groß Sieg.
Wenn Sie viele Spalten zusammenstellen müssen und eine oder mehrere sehr lang sind, können Sie auch eine innere Schleife erstellen, um dasselbe zu tun und zu verwenden implode()
um die values-Klausel dem äußeren Array zuzuweisen.
-
Dank dafür! Übrigens fehlt eine schließende Klammer am Ende der Funktion, falls jemand vorhat, sie zu kopieren. mysql_real_query(‘INSERT INTO table VALUES (text, category) ‘.implode(‘,’. $sql));
– zuweitseitlich
23. April 2009 um 2:21 Uhr
-
Danke! Fest. (das mache ich oft…)
– Statiksan
23. April 2009 um 2:30 Uhr
-
Ich glaube, dieser Code wird eine Lösung für mein neuestes Projekt schaffen. Meine Frage hier ist, ist dies sicher vor SQL-Injection? Meine Pläne sind zu wechseln
mysql_real_escape_string
mitmysqli_real_escape_string
undmysql_query
mitmysqli_query
da ich MySQLi verwende und diese seit PHP5 veraltet sind. Danke vielmals!– Wortmann
24. Januar 2014 um 18:11 Uhr
-
Diese Abfrage ist anfällig für SQL-Injection!
– Hedeshy
9. Dezember 2015 um 9:50 Uhr
-
mysql_*
wurde aus PHP entfernt, verwenden Sie also unbedingt diemysqli_*
Schnittstelle.– Rick James
3. November 2018 um 16:37 Uhr
Somnath Muluk
Mehrfaches Einfügen/Batch-Einfügen wird jetzt von CodeIgniter unterstützt.
$data = array(
array(
'title' => 'My title' ,
'name' => 'My Name' ,
'date' => 'My date'
),
array(
'title' => 'Another title' ,
'name' => 'Another Name' ,
'date' => 'Another date'
)
);
$this->db->insert_batch('mytable', $data);
// Produces: INSERT INTO mytable (title, name, date) VALUES ('My title', 'My name', 'My date'), ('Another title', 'Another name', 'Another date')
-
Ich denke, dies ist die am meisten empfohlene Methode zum Einfügen mehrerer Zeilen, anstatt mysql_query zu verwenden. Denn wenn wir ein Framework verwenden, ist es eine gute Praxis, immer integrierte Funktionen des Frameworks zu verwenden.
– Praneeth Nidarshan
24. Januar 2018 um 1:57 Uhr
Espresso_Junge
Sie könnten die Abfrage für das Einfügen einer Zeile mit der Klasse mysqli_stmt vorbereiten und dann über das Datenarray iterieren. Etwas wie:
$stmt = $db->stmt_init();
$stmt->prepare("INSERT INTO mytbl (fld1, fld2, fld3, fld4) VALUES(?, ?, ?, ?)");
foreach($myarray as $row)
{
$stmt->bind_param('idsb', $row['fld1'], $row['fld2'], $row['fld3'], $row['fld4']);
$stmt->execute();
}
$stmt->close();
Wobei „idsb“ die Typen der Daten sind, die Sie binden (int, double, string, blob).
-
Ich habe kürzlich einige Benchmarks durchgeführt, bei denen Bulk-Insert- und vorbereitete Insert-Anweisungen verglichen wurden, wie hier erwähnt. Für etwa 500 Beilagen dauerte die Methode der vorbereiteten Beilagen zwischen 2,6 und 4,4 Sekunden und die Methode der Massenbeilage in 0,12 bis 0,35 Sekunden. Ich hätte gedacht, mysql hätte diese vorbereiteten Anweisungen “geballt” und genauso gut funktioniert wie die Masseneinfügungen, aber in einer Standardkonfiguration ist der Leistungsunterschied anscheinend enorm. (Übrigens wurden alle Benchmark-Abfragen für jeden Test in einer einzigen Transaktion ausgeführt, um ein automatisches Commit zu verhindern.)
– Motin
27. Juli 2011 um 16:53 Uhr
Ross Schnitzer
mysqli in PHP 5 ist ein Objekt mit einigen guten Funktionen, mit denen Sie die Einfügezeit für die obige Antwort beschleunigen können:
$mysqli->autocommit(FALSE);
$mysqli->multi_query($sqlCombined);
$mysqli->autocommit(TRUE);
Das Deaktivieren von Autocommit beim Einfügen vieler Zeilen beschleunigt das Einfügen erheblich, also schalten Sie es aus, führen Sie es dann wie oben erwähnt aus, oder erstellen Sie einfach eine Zeichenfolge (sqlCombined), die aus vielen Einfügeanweisungen besteht, die durch Semikolons getrennt sind, und die Mehrfachabfrage wird sie gut verarbeiten.
vezult
Sie könnten immer mysql verwenden LOAD DATA
:
LOAD DATA LOCAL INFILE '/full/path/to/file/foo.csv' INTO TABLE `footable` FIELDS TERMINATED BY ',' LINES TERMINATED BY '\r\n'
Bulk-Inserts zu machen, anstatt einen Haufen davon zu verwenden INSERT
Aussagen.
-
Ich hatte mir das angesehen, aber ich muss die Daten manipulieren, bevor ich sie einfüge. Es wurde mir als kartesisches Produkt eines 1400 mal 1400 großen Satzes von int-Werten gegeben, von denen viele Null sind. Ich muss das in eine Viele-zu-Viele-Beziehung umwandeln, indem ich eine Zwischentabelle verwende, um Platz zu sparen, daher sind Einfügungen im Gegensatz zu einer Masseneinfügung erforderlich
– zuweitseitlich
23. April 2009 um 2:26 Uhr
-
Sie können immer eine CSV-Datei generieren, nachdem Sie sie bearbeitet und die mysql-Anweisung aufgerufen haben, die die Daten lädt
– Alexander Jardim
28. Juni 2013 um 18:55 Uhr
-
Ich denke, es ist hilfreich zu wissen, dass der Pfad lokal zu Ihrem SQL-Client und nicht auf dem SQL-Server ist. Die Datei wird auf den Server hochgeladen und dann von diesem gelesen. Ich dachte, die Datei müsste schon auf dem Server sein, was nicht der Fall ist. Wenn es sich bereits auf dem Server befindet, entfernen Sie die
LOCAL
bisschen.– Kyle
12. Dezember 2017 um 21:22 Uhr
bdl
Nun, Sie möchten nicht 1000 Abfrageaufrufe ausführen, aber das ist in Ordnung:
$stmt= array( 'array of statements' );
$query= 'INSERT INTO yourtable (col1,col2,col3) VALUES ';
foreach( $stmt AS $k => $v ) {
$query.= '(' .$v. ')'; // NOTE: you'll have to change to suit
if ( $k !== sizeof($stmt)-1 ) $query.= ', ';
}
$r= mysql_query($query);
Abhängig von Ihrer Datenquelle kann das Füllen des Arrays so einfach sein wie das Öffnen einer Datei und das Ausgeben des Inhalts in ein Array via file()
.
-
Ich hatte mir das angesehen, aber ich muss die Daten manipulieren, bevor ich sie einfüge. Es wurde mir als kartesisches Produkt eines 1400 mal 1400 großen Satzes von int-Werten gegeben, von denen viele Null sind. Ich muss das in eine Viele-zu-Viele-Beziehung umwandeln, indem ich eine Zwischentabelle verwende, um Platz zu sparen, daher sind Einfügungen im Gegensatz zu einer Masseneinfügung erforderlich
– zuweitseitlich
23. April 2009 um 2:26 Uhr
-
Sie können immer eine CSV-Datei generieren, nachdem Sie sie bearbeitet und die mysql-Anweisung aufgerufen haben, die die Daten lädt
– Alexander Jardim
28. Juni 2013 um 18:55 Uhr
-
Ich denke, es ist hilfreich zu wissen, dass der Pfad lokal zu Ihrem SQL-Client und nicht auf dem SQL-Server ist. Die Datei wird auf den Server hochgeladen und dann von diesem gelesen. Ich dachte, die Datei müsste schon auf dem Server sein, was nicht der Fall ist. Wenn es sich bereits auf dem Server befindet, entfernen Sie die
LOCAL
bisschen.– Kyle
12. Dezember 2017 um 21:22 Uhr
Nikunj Dhimar
$query= array();
foreach( $your_data as $row ) {
$query[] = '("'.mysql_real_escape_string($row['text']).'", '.$row['category_id'].')';
}
mysql_query('INSERT INTO table (text, category) VALUES '.implode(',', $query));
Ich habe Ihre Frage zum mehrreihigen Einsatz von Codeigniter beantwortet.
– Somnath Muluk
19. Dezember 2012 um 5:24 Uhr
@SomnathMuluk Danke, aber es ist schon eine Weile her, dass ich diese Frage beantworten musste 🙂 …
– zuweitseitlich
19. Dezember 2012 um 17:39 Uhr
Ich würde empfehlen, die insert_batch-Funktion von CodeIgniter zu verwenden. Wenn Sie eine Bibliothek verwenden, versuchen Sie immer, ihre Stärken und Codierungsstandards zu nutzen.
– DewaldEls
30. Januar 2017 um 11:14 Uhr
Ich glaube, Insert Batch ist der beste Weg, dies zu tun, siehe den Link stackoverflow.com/questions/27206178/codeigniter-insert-batch
– Syed Amir Bukhari
9. Januar 2018 um 6:14 Uhr