wstawianie wielu wierszy za pomocą tablicy php do mysql
Przekazuję duży zbiór danych do tabeli MySQL za pomocą PHP za pomocą poleceń insert i zastanawiam się, czy możliwe jest wstawianie około 1000 wierszy na raz za pomocą zapytania innego niż dołączanie każdej wartości na końcu ciągu o długości mili, a następnie jego wykonanie. Używam frameworka CodeIgniter, więc jego funkcje są również dostępne dla mnie.
13 answers
Złożenie jednej instrukcji INSERT
z wieloma wierszami jest znacznie szybsze w MySQL niż jedna instrukcja INSERT
na wiersz.
To powiedziawszy, wygląda na to, że możesz mieć problemy z obsługą łańcuchów w PHP, co tak naprawdę jest problemem algorytmów, a nie językowym. Zasadniczo, podczas pracy z dużymi strunami, chcesz zminimalizować niepotrzebne kopiowanie. Przede wszystkim oznacza to, że chcesz uniknąć konkatenacji. Najszybszy i najbardziej wydajny sposób na zbudowanie dużego ciągu, np. do wstawiania setki wierszy na jednym, jest skorzystanie z funkcji implode()
i przypisania tablicy.
$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));
Zaletą tego podejścia jest to, że nie kopiujesz i nie kopiujesz instrukcji SQL, którą do tej pory zgromadziłeś przy każdej konkatenacji; zamiast tego PHP robi to raz w instrukcji implode()
. To jest Wielkie zwycięstwo.
Jeśli masz wiele kolumn do złożenia, a jedna lub więcej są bardzo długie, możesz również zbudować wewnętrzną pętlę, aby zrobić to samo i użyć implode()
, aby Przypisz klauzulę values do zewnętrznej tablicy.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-20 14:33:12
Multiple insert / batch insert jest teraz obsługiwany przez codeigniter. Miałem ten sam problem. Chociaż jest bardzo późno na odpowiedź na pytanie, to komuś pomoże. Dlatego odpowiadam na to pytanie.
$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')
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-21 12:41:04
Można przygotować zapytanie do wstawiania jednego wiersza za pomocą klasy mysqli_stmt, a następnie iterację nad tablicą danych. Coś w stylu:
$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();
Gdzie 'idsb' są typami danych, które chcesz powiązać (int, double, string, blob).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-23 02:06:19
Wiem, że to stare zapytanie, ale właśnie czytałem i pomyślałem, że dodam to, co znalazłem gdzie indziej:
Mysqli w PHP 5 to ojbect z kilkoma dobrymi funkcjami, które pozwolą Ci przyspieszyć czas wstawiania odpowiedzi powyżej:
$mysqli->autocommit(FALSE);
$mysqli->multi_query($sqlCombined);
$mysqli->autocommit(TRUE);
Wyłączenie autocommit podczas wstawiania wielu wierszy znacznie przyspiesza wstawianie, więc wyłącz go, a następnie wykonaj jak wspomniano powyżej, lub po prostu wykonaj łańcuch (sqlCombined), który jest wieloma instrukcjami insert oddzielonymi średnikami i wieloma zapytaniami. zajmij się nimi dobrze.
Mam nadzieję, że pomoże to komuś zaoszczędzić czas (wyszukiwanie i wstawianie!)
R
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-07 15:21:21
Zawsze możesz użyć mysql ' s LOAD DATA
:
LOAD DATA LOCAL INFILE '/full/path/to/file/foo.csv' INTO TABLE `footable` FIELDS TERMINATED BY ',' LINES TERMINATED BY '\r\n'
Do wykonywania masowych wstawek zamiast używania kilku INSERT
instrukcji.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-23 02:15:31
Cóż, nie chcesz wykonać 1000 zapytań, ale robienie tego jest w porządku:
$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);
W zależności od źródła danych, wypełnienie tablicy może być tak proste, jak otwarcie pliku i wrzucenie zawartości do tablicy za pomocą file()
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-23 02:04:06
$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));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-20 11:28:02
Stworzyłem klasę, która wykonuje multi-line, która jest używana w następujący sposób:
$pdo->beginTransaction();
$pmi = new PDOMultiLineInserter($pdo, "foo", array("a","b","c","e"), 10);
$pmi->insertRow($data);
// ....
$pmi->insertRow($data);
$pmi->purgeRemainingInserts();
$pdo->commit();
Gdzie klasa jest zdefiniowana następująco:
class PDOMultiLineInserter {
private $_purgeAtCount;
private $_bigInsertQuery, $_singleInsertQuery;
private $_currentlyInsertingRows = array();
private $_currentlyInsertingCount = 0;
private $_numberOfFields;
private $_error;
private $_insertCount = 0;
/**
* Create a PDOMultiLine Insert object.
*
* @param PDO $pdo The PDO connection
* @param type $tableName The table name
* @param type $fieldsAsArray An array of the fields being inserted
* @param type $bigInsertCount How many rows to collect before performing an insert.
*/
function __construct(PDO $pdo, $tableName, $fieldsAsArray, $bigInsertCount = 100) {
$this->_numberOfFields = count($fieldsAsArray);
$insertIntoPortion = "REPLACE INTO `$tableName` (`".implode("`,`", $fieldsAsArray)."`) VALUES";
$questionMarks = " (?".str_repeat(",?", $this->_numberOfFields - 1).")";
$this->_purgeAtCount = $bigInsertCount;
$this->_bigInsertQuery = $pdo->prepare($insertIntoPortion.$questionMarks.str_repeat(", ".$questionMarks, $bigInsertCount - 1));
$this->_singleInsertQuery = $pdo->prepare($insertIntoPortion.$questionMarks);
}
function insertRow($rowData) {
// @todo Compare speed
// $this->_currentlyInsertingRows = array_merge($this->_currentlyInsertingRows, $rowData);
foreach($rowData as $v) array_push($this->_currentlyInsertingRows, $v);
//
if (++$this->_currentlyInsertingCount == $this->_purgeAtCount) {
if ($this->_bigInsertQuery->execute($this->_currentlyInsertingRows) === FALSE) {
$this->_error = "Failed to perform a multi-insert (after {$this->_insertCount} inserts), the following errors occurred:".implode('<br/>', $this->_bigInsertQuery->errorInfo());
return false;
}
$this->_insertCount++;
$this->_currentlyInsertingCount = 0;
$this->_currentlyInsertingRows = array();
}
return true;
}
function purgeRemainingInserts() {
while ($this->_currentlyInsertingCount > 0) {
$singleInsertData = array();
// @todo Compare speed - http://www.evardsson.com/blog/2010/02/05/comparing-php-array_shift-to-array_pop/
// for ($i = 0; $i < $this->_numberOfFields; $i++) $singleInsertData[] = array_pop($this->_currentlyInsertingRows); array_reverse($singleInsertData);
for ($i = 0; $i < $this->_numberOfFields; $i++) array_unshift($singleInsertData, array_pop($this->_currentlyInsertingRows));
if ($this->_singleInsertQuery->execute($singleInsertData) === FALSE) {
$this->_error = "Failed to perform a small-insert (whilst purging the remaining rows; the following errors occurred:".implode('<br/>', $this->_singleInsertQuery->errorInfo());
return false;
}
$this->_currentlyInsertingCount--;
}
}
public function getError() {
return $this->_error;
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-28 06:44:47
Użyj insert batch w codeigniter, aby wstawić wiele wierszy danych.
$this->db->insert_batch('tabname',$data_array); // $data_array holds the value to be inserted
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-06 11:46:16
Możesz to zrobić na kilka sposobów w codeigniter np.
First By loop
foreach($myarray as $row)
{
$data = array("first"=>$row->first,"second"=>$row->sec);
$this->db->insert('table_name',$data);
}
Second -- by insert batch
$data = array(
array(
'first' => $myarray[0]['first'] ,
'second' => $myarray[0]['sec'],
),
array(
'first' => $myarray[1]['first'] ,
'second' => $myarray[1]['sec'],
),
);
$this->db->insert_batch('table_name', $data);
Third way -- by multiple value pass
$sql = array();
foreach( $myarray as $row ) {
$sql[] = '("'.mysql_real_escape_string($row['first']).'", '.$row['sec'].')';
}
mysql_query('INSERT INTO table (first, second) VALUES '.implode(',', $sql));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-22 10:34:26
Stworzyłem tę prostą funkcję, z której możecie łatwo korzystać. Musisz podać nazwę tabeli ($tbl)
, pole table ($insertFieldsArr)
przeciwko wstawianiu danych, tablica danych ($arr)
.
insert_batch('table',array('field1','field2'),$dataArray);
function insert_batch($tbl,$insertFieldsArr,$arr){ $sql = array();
foreach( $arr as $row ) {
$strVals='';
$cnt=0;
foreach($insertFieldsArr as $key=>$val){
if(is_array($row)){
$strVals.="'".mysql_real_escape_string($row[$cnt]).'\',';
}
else{
$strVals.="'".mysql_real_escape_string($row).'\',';
}
$cnt++;
}
$strVals=rtrim($strVals,',');
$sql[] = '('.$strVals.')';
}
$fields=implode(',',$insertFieldsArr);
mysql_query('INSERT INTO `'.$tbl.'` ('.$fields.') VALUES '.implode(',', $sql));
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-14 14:51:57
Chociaż jest już za późno, aby odpowiedzieć na to pytanie. Oto moja odpowiedź na to samo.
Jeśli używasz CodeIgniter, możesz użyć wbudowanych metod zdefiniowanych w klasie query_builder.
$this - > db- > insert_batch()
Generuje łańcuch wstawiania na podstawie dostarczonych danych i uruchamia zapytanie. Do funkcji można przekazać tablicę lub obiekt. Oto przykład użycia tablicy:
$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')
Pierwszy parametr będzie zawierał nazwa tabeli, Druga to asocjacyjna tablica wartości.
Więcej informacji na temat query_builder znajdziesz tutajWarning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-16 13:04:32
use this in codeigniter for multiple data insertion
$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')
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-13 12:33:32