2009-09-28 4 views
2

prepared statement가 여러 VALUES를 가진 보통의 mysql_query와 똑같이 작동하는지 궁금합니다.PHP MySQLi 다중 삽입

INSERT INTO table (a,b) VALUES ('a','b'), ('c','d'); 

VS

$sql = $db->prepare('INSERT INTO table (a,b) VALUES (?, ?); 

내가 루프에서 준비된 문을 사용하면, MySQL이이 코드의 첫 번째 부분에서와 같이 작업을 백그라운드에서 삽입을 최적화하거나 단지입니다 매번 한 값을 가진 루프 내에서 첫 번째 코드를 실행하는 것처럼?

답변

10

하나의 쿼리가 준비된 문을 사용하고 다른 쿼리가 전체 쿼리를 작성한 다음 테스트를 실행했습니다. 아마 이해하기 쉬운 것을 만들고 싶지 않을 것입니다.

여기에 내 테스트 코드가 있습니다. 나는 $ stmt-> close()가 호출 될 때까지 준비된 명령문이 일종의 실행을 유지한다고 생각했다. real_escape_string을 사용하여 쿼리를 작성하는 테스트가 적어도 10 배 더 빠르기 때문에 실제로는 그렇지 않습니다.

<?php 

$db = new mysqli('localhost', 'user', 'pass', 'test'); 

$start = microtime(true); 
$a = 'a'; 
$b = 'b'; 

$sql = $db->prepare('INSERT INTO multi (a,b) VALUES(?, ?)'); 
$sql->bind_param('ss', $a, $b); 
for($i = 0; $i < 10000; $i++) 
{ 
    $a = chr($i % 1); 
    $b = chr($i % 2); 
    $sql->execute(); 
} 
$sql->close(); 

echo microtime(true) - $start; 

$db->close(); 

?> 
+3

비슷한 것을 원했습니다 (여러 삽입),이 답변이 올바른 것으로 표시되었으므로 최적화 된 솔루션입니까? 또한 "real_escape_string을 사용하여 쿼리를 작성하는 테스트가 적어도 10 배 더 빠릅니다." 그 시험은 어디에 있습니까? –

0

준비된 문을 루프에서 사용하면 준비된 문으로 한 번만 수행해야하는 분석 때문에 매번 원시 쿼리를 실행하는 것보다 효율적입니다. 그래서 아닙니다, 그 정도까지는 동일하지 않습니다.

+2

그러나 다중 행 삽입 구문을 사용하면 데이터베이스에 쿼리를 한 번만 전송하므로 여러 요청의 오버 헤드가 줄어들 기 때문에 더 빠릅니다. – andho

0
public function insertMulti($table, $columns = array(), $records = array(), $safe = false) { 
    self::$counter++; 
    //Make sure the arrays aren't empty 
    if (empty($columns) || empty($records)) { 
     return false; 
    } 

    // If set safe to true: set records values to html real escape safe html 
    if($safe === true){ 
     $records = $this->filter($records); 
    } 

    //Count the number of fields to ensure insertion statements do not exceed the same num 
    $number_columns = count($columns); 

    //Start a counter for the rows 
    $added = 0; 

    //Start the query 
    $sql = "INSERT INTO " . $table; 

    $fields = array(); 
    //Loop through the columns for insertion preparation 
    foreach ($columns as $field) { 
     $fields[] = '`' . $field . '`'; 
    } 
    $fields = ' (' . implode(', ', $fields) . ')'; 

    //Loop through the records to insert 
    $values = array(); 
    foreach ($records as $record) { 
     //Only add a record if the values match the number of columns 
     if (count($record) == $number_columns) { 
      $values[] = '(\'' . implode('\', \'', array_values($record)) . '\')'; 
      $added++; 
     } 
    } 
    $values = implode(', ', $values); 

    $sql .= $fields . ' VALUES ' . $values; 
    //echo $sql; 
    $query = $this->dbConnection->query($sql); 

    if ($this->dbConnection->error) { 
     $this->errorLog($this->dbConnection->error, $sql); 
     return false; 
    } else { 
     return $added; 
    } 
} 

제 여러 행 값과 상기 하나 INSERT 쿼리를 준비하고 한번 삽입에 대한이 함수. 그러나 이것은 일괄 삽입을위한 것이 아닙니다.