2009-09-28 2 views
2

Мне интересно, работают ли подготовленные операторы так же, как и обычная mysql_query с несколькими значениями VALUES.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; 
    } 
} 

Эта функция сначала подготовить один ВСТАВИТЬ запрос с несколькими значениями строк и вставить его один раз. Но это не для объемной вставки сразу.

Смежные вопросы