다음은 대량 삽입에 사용되는 내 PDO 작업 장치의 방법입니다. 여러 VALUES 항목이있는 단일 INSERT 문을 작성합니다.
(여기에 사용되는 몇 가지 방법은, 코드 조각에 포함되지 특히 $this->connect()
(PDO에 연결) 방법이 복잡한 클래스 정의에서 싹둑가, $this->begin()
이므로주의 해주십시오
$db->bulkinsert(
'tbl_my_tablename',
array('fieldname_1','fieldname_2', 'fieldname_3'),
array(
/* rec1 */ array('r1f1', 'r1f2', 'r1f3'),
/* rec2 */ array('r2f1', 'r2f2', 'r2f3'),
/* rec3 */ array('r3f1', 'r3f2', 'r3f3')
));
로 사용 $this->commit()
및 $this->rollback()
) 및 로깅을위한 정적 인 Log
클래스는 Apache Commons와 유사합니다 .-)
하지만 이것이 필요한 것 같습니다.
/**
* Performs fast bulk insertion
* Parameters:
* $tablename
* $datafields - non-assiciative array of fieldnames
* or propertynames if $data is an array of objects
* $data - array of either non-associative arrays (in the correct order)
* or array of objects with property names matching the $datafields array
*/
const MAX_BULK_DATA = 3000;
public function bulkinsert($tablename, $datafields, &$data) {
$result = 0;
try {
try {
$this->connect();
$datacount = count($data);
// loop until all data has been processed
$start = 0;
$lastbinds = 0;
$this->begin();
while ($start < $datacount) {
$ins = array();
$bindscount = min(self::MAX_BULK_DATA, $datacount - $start);
if ($bindscount != $lastbinds) {
// prepare the binds
$binds = substr(str_repeat(',?', count($datafields)), 1);
$binds = substr(str_repeat(",($binds)", $bindscount), 1);
$lastbinds = $bindscount;
}
for ($go = $start, $last = $start + $bindscount; $go < $last; $go++) {
if (is_object($data[$go])) {
try {
foreach($datafields as $propname) {
$rfl = new ReflectionProperty($data[$go], $propname);
$rfl->setAccessible(true);
$ins[] = $rfl->getValue($data[$go]);
}
}
catch(ReflectionException $e) {
throw new InvalidArgumentException('PDOCONNECT_ERR_SQL_UNKNOWN_PROPERTY', 0, $e);
}
}
else {
foreach($data[$go] as $value) {
$ins[] = $value;
}
}
}
$sql = sprintf('INSERT INTO %s (%s) VALUES %s', $tablename, join(',',$datafields), $binds);
Log::trace($sql);
$stmt = $this->pdo->prepare($sql);
$stmt->execute($ins);
$start = $last;
$result += $bindscount;
}
$this->commit();
}
catch(PDOException $e) {
// do something with the exception if necessary
throw $e;
}
}
catch(Exception $e) {
$this->rollback();
throw $e;
}
return $result;
}
}
concat 쿼리가 MySQL의 서버 (최대 1Mb) 설정에서 벗어나는 경우 계산해야하기 때문에 PHP concat는 메모리와 CPU 전원도 사용합니다. –
예. 루프 내에서 전체 쿼리 문자열 ("INSERT INTO table VALUES"제외)을 작성한 다음 루프가 완료되면 실행하십시오. 그렇게하면 데이터베이스로의 왕복은 단 하나입니다. – Strawberry