PDO准备好的插入语句可以在单个查询中插入多行数据。

178

我目前正在使用这种类型的SQL在MySQL上插入多行值:

INSERT INTO `tbl` (`key1`,`key2`) VALUES ('r1v1','r1v2'),('r2v1','r2v2'),...

根据PDO的读取,使用预处理语句应该比静态查询更安全。

因此,我想知道是否有可能使用预处理语句生成“使用一条查询插入多行值”的功能。

如果是,请问我该如何实现?


在处理 $stmt->execute($data); 的答案时要小心,详见 http://php.net/manual/en/pdostatement.execute.php#refsect1-pdostatement.execute-parameters 。基本上所有的参数都被作为字符串传递并验证。在构建查询后,只需循环遍历数据,并手动使用 bindValuebindParam 方法,将类型作为第三个参数传递即可。 - MrMesees
25个回答

178
使用PDO准备语句进行多值插入
在一个execute语句中插入多个值。为什么呢?因为根据这个页面的说法,这比常规插入更快。
$data[] = ['valueA1', 'valueB1'];
$data[] = ['valueA2', 'valueB2'];

更多的数据值或者你可能有一个循环来填充数据。
基本上,这就是我们想要插入语句看起来的样子:
insert into table (fielda, fieldb, ... ) values (?,?...), (?,?...)....

所以,对于准备好的插入语句,你需要知道字段的数量来创建一个VALUES部分,并且需要知道行的数量来确定重复的次数。
现在,看一下代码:
// create the ?,? sequence for a single row
$values = str_repeat('?,', count($data[0]) - 1) . '?';
// construct the entire query
$sql = "INSERT INTO table (columnA, columnB) VALUES " .
    // repeat the (?,?) sequence for each row
    str_repeat("($values),", count($data) - 1) . "($values)";    

$stmt = $pdo->prepare ($sql);
// execute with all values from $data
$stmt->execute(array_merge(...$data));

请注意,这种方法是100%安全的,因为查询完全由代码中明确编写的常量部分构建,特别是列名。

4
上面的解释中提到了$datafields,但在$sql中使用的是$datafield。因此,复制粘贴将导致错误。请进行更正。感谢这个解决方案。 - pal4life
1
array_merge似乎比仅使用array_push更昂贵。 - K2xL
1
如果有人喜欢的话:还有一个库 https://github.com/auraphp/Aura.SqlQuery/tree/2.4.0#multiple-row-bulk-insert - Hari K T
23
当您说“只有1秒的差别”时,您插入了多少行数据?根据上下文,1秒可能非常显着。 - Kevin Dice
3
优化:没有必要一遍又一遍地调用 placeholders()。在循环之前只需调用一次并使用 sizeof($datafields),然后将结果字符串附加到循环中的 $question_marks[] 中。 - AVIDeveloper
显示剩余5条评论

86
和Balagtas先生的答案一样,稍微清晰一点...
最近版本的MySQL和PHP PDO确实支持多行INSERT语句。
SQL概述
假设您想要插入到一个有3列的表中,SQL代码将类似于以下内容。
INSERT INTO tbl_name
            (colA, colB, colC)
     VALUES (?, ?, ?), (?, ?, ?), (?, ?, ?) [,...]

ON DUPLICATE KEY UPDATE即使在多行插入时也能按预期工作;追加此内容:

ON DUPLICATE KEY UPDATE colA = VALUES(colA), colB = VALUES(colB), colC = VALUES(colC)

PHP概述

您的PHP代码将遵循通常的$pdo->prepare($qry)$stmt->execute($params) PDO调用。

$params将是一个一维数组,包含要传递给INSERT的所有值。

在上面的示例中,它应该包含9个元素;PDO将使用每组3个元素作为单个值行。(插入3行,每行3列= 9个元素的数组。)

实现

下面的代码是为了清晰起见而编写的,而不是为了效率。如果需要,可以使用PHP的array_*()函数来更好地映射或遍历数据。假设每个查询都是独立的事务,因此不需要显式事务。

假设:

  • $dataVals - 多维数组,其中每个元素是要插入的一行值的一维数组

示例代码

// setup data values for PDO. No memory overhead thanks to copy-on-write
$dataToInsert = array();
foreach ($dataVals as $row) {
    foreach($row as $val) {
        $dataToInsert[] = $val;
    }
}

$onDup = "ON DUPLICATE KEY UPDATE colA=VALUES(colA)"; // optional

// setup the placeholders - a fancy way to make the long "(?, ?, ?)..." string
$rowPlaces = '(' . implode(', ', array_fill(0, count($colNames), '?')) . ')';
$allPlaces = implode(', ', array_fill(0, count($dataVals), $rowPlaces));

$sql = "INSERT INTO `tblName` (`colA`, `colB, colC)" . 
    " VALUES $allPlaces ON DUPLICATE KEY UPDATE $onDup";

// and then the PHP PDO boilerplate
$stmt = $pdo->prepare ($sql);
$stmt->execute($dataToInsert);

10
很遗憾,PDO在处理这个问题上的方式确实太糟糕了。其他数据库驱动程序有一些非常优雅的方法来解决这个问题。 - Jonathon
这将占位符设置得更加简洁,使$rowPlaces不再必要:$allPlaces = implode(',', array_fill(0, count($dataVals), '('.str_pad('', (count($colNames)*2)-1, '?,').')')); - Phil
完美运作。我会在这个答案中补充需要确保表中索引的唯一性(组合)。就像在ALTER TABLE votes ADD UNIQUE unique_index(user, email, address);中所示。 - Giuseppe
2
太棒了!顺便说一下,使用array_push($dataToInsert, ...array_values($dataVals));foreach ($dataVals as $row => $data) {}要快得多。 - Anis

47

就我所知,许多用户建议通过迭代INSERT语句而不是构建单个字符串查询来完成操作。我决定运行一个只有两个字段和非常基本的插入语句的简单测试:

<?php
require('conn.php');

$fname = 'J';
$lname = 'M';

$time_start = microtime(true);
$stmt = $db->prepare('INSERT INTO table (FirstName, LastName) VALUES (:fname, :lname)');

for($i = 1; $i <= 10; $i++ )  {
    $stmt->bindParam(':fname', $fname);
    $stmt->bindParam(':lname', $lname);
    $stmt->execute();

    $fname .= 'O';
    $lname .= 'A';
}


$time_end = microtime(true);
$time = $time_end - $time_start;

echo "Completed in ". $time ." seconds <hr>";

$fname2 = 'J';
$lname2 = 'M';

$time_start2 = microtime(true);
$qry = 'INSERT INTO table (FirstName, LastName) VALUES ';
$qry .= "(?,?), ";
$qry .= "(?,?), ";
$qry .= "(?,?), ";
$qry .= "(?,?), ";
$qry .= "(?,?), ";
$qry .= "(?,?), ";
$qry .= "(?,?), ";
$qry .= "(?,?), ";
$qry .= "(?,?), ";
$qry .= "(?,?)";

$stmt2 = $db->prepare($qry);
$values = array();

for($j = 1; $j<=10; $j++) {
    $values2 = array($fname2, $lname2);
    $values = array_merge($values,$values2);

    $fname2 .= 'O';
    $lname2 .= 'A';
}

$stmt2->execute($values);

$time_end2 = microtime(true);
$time2 = $time_end2 - $time_start2;

echo "Completed in ". $time2 ." seconds <hr>";
?>

虽然整个查询本身只需要毫秒级别的时间,但是后一个(单字符串)查询总是比较快,速度通常快8倍或更多。如果在更多的列上导入数千行数据,这种差异可能会变得非常大。


@JM4 - 把10行直接放在一个执行中是个好主意。但是如果它们存储在像JSON这样的对象中,我该如何插入成千上万行?我的下面的代码完美地工作。但是我该如何调整它以在一个执行中插入10行?foreach($json_content as $datarow) { $id = $datarow[id]; $date = $datarow[date]; $row3 = $datarow[row3]; $row4 = $datarow[row4]; $row5 = $datarow[row5]; $row6 = $datarow[row6]; $row7= $datarow[row7]; // 现在执行 $databaseinsert->execute(); } // 结束循环 - Peter
@JM4 - 我的第二个问题是:“为什么第二个导入例程中没有bind_param语句?” - Peter
你不是需要循环两次吗?你还需要动态生成 (?,?),对吧? - NoobishPro
@NoobishPro 是的,你可以使用相同的 for/foreach 来生成两者。 - Chazy Chaz
你应该将多个语句包裹在一个事务中。太糟糕了,你没有这样做。 - Your Common Sense
你应该把多个语句放在一个事务中进行处理。真可惜你没有这样做。 - undefined

40
请注意,此答案已过时。现在PHP可以使用array_merge(...$data)一次性合并所有数组,而无需使用任何循环。
当$data数组较小时,Herbert Balagtas的"被接受的答案"效果良好。但对于较大的$data数组,array_merge函数的速度变得极慢。我用于创建$data数组的测试文件有28列,大约有80,000行。最终脚本完成所需41秒
改用array_push()创建$insert_values而不是array_merge()可使执行时间提高100倍,仅需要0.41秒
有问题的array_merge():
$insert_values = array();

foreach($data as $d){
 $question_marks[] = '('  . placeholders('?', sizeof($d)) . ')';
 $insert_values = array_merge($insert_values, array_values($d));
}

为了避免使用array_merge()函数,您可以构建以下两个数组:
//Note that these fields are empty, but the field count should match the fields in $datafields.
$data[] = array('','','','',... n ); 

//getting rid of array_merge()
array_push($insert_values, $value1, $value2, $value3 ... n ); 

这些数组可以按照以下方式使用:
function placeholders($text, $count=0, $separator=","){
    $result = array();
    if($count > 0){
        for($x=0; $x<$count; $x++){
            $result[] = $text;
        }
    }

    return implode($separator, $result);
}

$pdo->beginTransaction();

foreach($data as $d){
 $question_marks[] = '('  . placeholders('?', sizeof($d)) . ')';
}

$sql = "INSERT INTO table (" . implode(",", array_keys($datafield) ) . ") VALUES " . implode(',', $question_marks);

$stmt = $pdo->prepare($sql);
$stmt->execute($insert_values);
$pdo->commit();

4
在 PHP 5.6 中,您可以使用 array_push($data, ...array_values($row)) 代替 $data = array_merge($data, array_values($row));。速度更快。 - mpen
为什么是 5.6?文档没有提到 5.6,array_push() 在 PHP 4 中都可用。 - ZurabWeb
1
@Piero 这是 PHP 5.6+ 的代码,不是因为使用了 array_push(),而是因为 @Mark 使用了参数解包。注意那里的 ...array_values() 调用了吗? - mariano.iglesias
@mariano.iglesias array_values() 在 PHP 4 中也是可用的。不确定您所说的 argument unpacking 是否指的是它。 - ZurabWeb
我希望能够给你加一不止一次。非常好的解释。 - Abdul Rehman
4
@Piero,参数解包是 PHP 5.6 中引入的一项功能。它是一种将多个参数作为数组提供的方法。请在此处查看 - http://php.net/manual/en/migration56.new-features.php#migration56.new-features.splat - Anis

18
两种可能的方法:
$stmt = $pdo->prepare('INSERT INTO foo VALUES(:v1_1, :v1_2, :v1_3),
    (:v2_1, :v2_2, :v2_3),
    (:v2_1, :v2_2, :v2_3)');
$stmt->bindValue(':v1_1', $data[0][0]);
$stmt->bindValue(':v1_2', $data[0][1]);
$stmt->bindValue(':v1_3', $data[0][2]);
// etc...
$stmt->execute();

或者:

$pdo->beginTransaction();
$stmt = $pdo->prepare('INSERT INTO foo VALUES(:a, :b, :c)');
foreach($data as $item)
{
    $stmt->bindValue(':a', $item[0]);
    $stmt->bindValue(':b', $item[1]);
    $stmt->bindValue(':c', $item[2]);
    $stmt->execute();
}
$pdo->commit();

如果所有行的数据都在一个数组中,我会使用第二种解决方案。由于使用了事务,它几乎和第一种解决方案一样快。谢谢!

12
你在后者中是不是要进行多个(可能达到数千次)独立的执行调用,而不是将它们合并成一个语句? - JM4
@JM4,您是在建议将$stmt->execute();放在foreach循环之外吗? - bafromca
@bafromca - 是的,我是。请看我的回答,上面有赞。在一个纯插入语句中,我可以想到的逻辑上没有任何理由它不能是一个单一的语句。一个调用,一个执行。事实上,我2012年初的答案甚至可以进一步改进 - 我稍后会在有更多时间时做这件事。如果你开始混合使用插入/更新/删除组合,那就是另一回事了。 - JM4

11

你并不是用预处理语句的正确方式。

一个查询语句只能插入一行数据是可以接受的,因为你可以执行一个预处理语句,使用不同的参数多次插入数据。事实上,这是最大的优点之一,它允许你以高效、安全和方便的方式插入大量数据。

所以,你所提出的方案可能可以实现,至少对于固定数量的行来说是可以的,但几乎可以肯定的是,这不是你真正想要的。


1
你能提供一种更好的方法来向表中插入多行吗? - Crashthatch
@Crashthatch:就用朴素的方法吧:先设置一次预处理语句,然后为每一行使用不同的绑定参数值执行它。这是Zyk答案中的第二种方法。 - sebasgo
2
你提到的预处理语句的目的是正确的。但是,使用多重插入是另一种提高插入速度的技术,它也可以与预处理语句一起使用。 根据我的经验,在使用PDO预处理语句迁移3000万行数据时,我发现多重插入比分组单个插入在事务中快7-10倍。 - Anis
1
完全同意Anis的观点。我有10万行数据,使用多行插入可以大幅提高速度。 - Kenneth
声称在循环中每行调用关系型数据库通常是一件好事,这是我无法同意的。对此投反对票。当然,有时候这样做也可以。我不相信工程上的绝对性。但这是一个反模式,只应在特定情况下使用。 - Brandon

8
一个简短的回答:将按列排序的数据数组展开。
//$array = array( '1','2','3','4','5', '1','2','3','4','5');
$arCount = count($array);
$rCount = ($arCount  ? $arCount - 1 : 0);
$criteria = sprintf("(?,?,?,?,?)%s", str_repeat(",(?,?,?,?,?)", $rCount));
$sql = "INSERT INTO table(c1,c2,c3,c4,c5) VALUES$criteria";

当插入大约1000条记录时,您不想在只需要值计数时循环遍历每个记录进行插入。


4
这是我的简单方法。
    $values = array();
    foreach($workouts_id as $value){
      $_value = "(".$value.",".$plan_id.")";
      array_push($values,$_value);
    }
    $values_ = implode(",",$values);

    $sql = "INSERT INTO plan_days(id,name) VALUES" . $values_."";
    $stmt = $this->conn->prepare($sql);
    $stmt->execute();

7
你正在违背使用预处理语句的初衷。提问者关心的是在“阅读PDO文档时,使用预处理语句是否比静态查询更安全”的问题中的安全性。 - YesItsMe
2
想象一下,你有一个未经验证的 $workouts_id,它可能具有意外数据的 $value。你无法保证另一个开发人员在未来不会使这些数据不安全。因此,我认为最好使用PDO准备查询。 - Nikita_kharkov_ua
这个回答应该被删除。 - Your Common Sense
这个回答应该被删除。 - undefined

2

这是我编写的一个类,可以进行多次插入并带有清除选项:

<?php

/**
 * $pdo->beginTransaction();
 * $pmi = new PDOMultiLineInserter($pdo, "foo", array("a","b","c","e"), 10);
 * $pmi->insertRow($data);
 * ....
 * $pmi->insertRow($data);
 * $pmi->purgeRemainingInserts();
 * $pdo->commit();
 *
 */
class PDOMultiLineInserter {
    private $_purgeAtCount;
    private $_bigInsertQuery, $_singleInsertQuery;
    private $_currentlyInsertingRows  = array();
    private $_currentlyInsertingCount = 0;
    private $_numberOfFields;
    private $_error;
    private $_insertCount = 0;

    function __construct(\PDO $pdo, $tableName, $fieldsAsArray, $bigInsertCount = 100) {
        $this->_numberOfFields = count($fieldsAsArray);
        $insertIntoPortion = "INSERT 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;
    }
}

你好,Pierre。也许你在这里不再活跃了。尽管如此,我只是想指出我的这个问题的想法看起来几乎与你的一样。纯属巧合,因为我猜这没有更多的东西了。我还添加了DELETE和UPDATE操作的类,并从这里涉及了一些想法。我只是没有看到你的类。请原谅我在这里的无耻自我推销,但我想这对某些人会有所帮助。希望这不违反SO规则。在这里找到它。 - JackLeEmmerdeur

2

根据我的实验,我发现在单个事务中使用多行值的mysql插入语句是最快的。

然而,如果数据太多,则mysql的max_allowed_packet设置可能会限制具有多个值行的单个事务插入。因此,当数据大于mysql的max_allowed_packet大小时,以下函数将失败:

  1. singleTransactionInsertWithRollback
  2. singleTransactionInsertWithPlaceholders
  3. singleTransactionInsert

在插入大量数据的情况下,最成功的方法是transactionSpeed方法,但它消耗的时间比上述方法更长。因此,为了解决这个问题,您可以将数据分成较小的块并多次调用单个事务插入,或者通过使用transactionSpeed方法放弃执行速度。

以下是我的研究结果。

<?php

class SpeedTestClass
{
    private $data;

    private $pdo;

    public function __construct()
    {
        $this->data = [];
        $this->pdo = new \PDO('mysql:dbname=test_data', 'admin', 'admin');
        if (!$this->pdo) {
            die('Failed to connect to database');
        }
    }

    public function createData()
    {
        $prefix = 'test';
        $postfix = 'unicourt.com';
        $salutations = ['Mr.', 'Ms.', 'Dr.', 'Mrs.'];

        $csv[] = ['Salutation', 'First Name', 'Last Name', 'Email Address'];
        for ($i = 0; $i < 100000; ++$i) {
            $csv[] = [
                $salutations[$i % \count($salutations)],
                $prefix.$i,
                $prefix.$i,
                $prefix.$i.'@'.$postfix,
            ];
        }

        $this->data = $csv;
    }

    public function truncateTable()
    {
        $this->pdo->query('TRUNCATE TABLE `name`');
    }

    public function transactionSpeed()
    {
        $timer1 = microtime(true);
        $this->pdo->beginTransaction();
        $sql = 'INSERT INTO `name` (`first_name`, `last_name`) VALUES (:first_name, :last_name)';
        $sth = $this->pdo->prepare($sql);

        foreach (\array_slice($this->data, 1) as $values) {
            $sth->execute([
                ':first_name' => $values[1],
                ':last_name' => $values[2],
            ]);
        }

        // $timer2 = microtime(true);
        // echo 'Prepare Time: '.($timer2 - $timer1).PHP_EOL;
        // $timer3 = microtime(true);

        if (!$this->pdo->commit()) {
            echo "Commit failed\n";
        }
        $timer4 = microtime(true);
        // echo 'Commit Time: '.($timer4 - $timer3).PHP_EOL;

        return $timer4 - $timer1;
    }

    public function autoCommitSpeed()
    {
        $timer1 = microtime(true);
        $sql = 'INSERT INTO `name` (`first_name`, `last_name`) VALUES (:first_name, :last_name)';
        $sth = $this->pdo->prepare($sql);
        foreach (\array_slice($this->data, 1) as $values) {
            $sth->execute([
                ':first_name' => $values[1],
                ':last_name' => $values[2],
            ]);
        }
        $timer2 = microtime(true);

        return $timer2 - $timer1;
    }

    public function noBindAutoCommitSpeed()
    {
        $timer1 = microtime(true);

        foreach (\array_slice($this->data, 1) as $values) {
            $sth = $this->pdo->prepare("INSERT INTO `name` (`first_name`, `last_name`) VALUES ('{$values[1]}', '{$values[2]}')");
            $sth->execute();
        }
        $timer2 = microtime(true);

        return $timer2 - $timer1;
    }

    public function singleTransactionInsert()
    {
        $timer1 = microtime(true);
        foreach (\array_slice($this->data, 1) as $values) {
            $arr[] = "('{$values[1]}', '{$values[2]}')";
        }
        $sth = $this->pdo->prepare('INSERT INTO `name` (`first_name`, `last_name`) VALUES '.implode(', ', $arr));
        $sth->execute();
        $timer2 = microtime(true);

        return $timer2 - $timer1;
    }

    public function singleTransactionInsertWithPlaceholders()
    {
        $placeholders = [];
        $timer1 = microtime(true);
        $sql = 'INSERT INTO `name` (`first_name`, `last_name`) VALUES ';
        foreach (\array_slice($this->data, 1) as $values) {
            $placeholders[] = '(?, ?)';
            $arr[] = $values[1];
            $arr[] = $values[2];
        }
        $sql .= implode(', ', $placeholders);
        $sth = $this->pdo->prepare($sql);
        $sth->execute($arr);
        $timer2 = microtime(true);

        return $timer2 - $timer1;
    }

    public function singleTransactionInsertWithRollback()
    {
        $placeholders = [];
        $timer1 = microtime(true);
        $sql = 'INSERT INTO `name` (`first_name`, `last_name`) VALUES ';
        foreach (\array_slice($this->data, 1) as $values) {
            $placeholders[] = '(?, ?)';
            $arr[] = $values[1];
            $arr[] = $values[2];
        }
        $sql .= implode(', ', $placeholders);
        $this->pdo->beginTransaction();
        $sth = $this->pdo->prepare($sql);
        $sth->execute($arr);
        $this->pdo->commit();
        $timer2 = microtime(true);

        return $timer2 - $timer1;
    }
}

$s = new SpeedTestClass();
$s->createData();
$s->truncateTable();
echo "Time Spent for singleTransactionInsertWithRollback: {$s->singleTransactionInsertWithRollback()}".PHP_EOL;
$s->truncateTable();
echo "Time Spent for single Transaction Insert: {$s->singleTransactionInsert()}".PHP_EOL;
$s->truncateTable();
echo "Time Spent for single Transaction Insert With Placeholders: {$s->singleTransactionInsertWithPlaceholders()}".PHP_EOL;
$s->truncateTable();
echo "Time Spent for transaction: {$s->transactionSpeed()}".PHP_EOL;
$s->truncateTable();
echo "Time Spent for AutoCommit: {$s->noBindAutoCommitSpeed()}".PHP_EOL;
$s->truncateTable();
echo "Time Spent for autocommit with bind: {$s->autoCommitSpeed()}".PHP_EOL;
$s->truncateTable();

一个只包含两列的表格有 100,000 个条目的结果如下:

Original Answer 翻译成 "最初的回答"

$ php data.php
Time Spent for singleTransactionInsertWithRollback: 0.75147604942322
Time Spent for single Transaction Insert: 0.67445182800293
Time Spent for single Transaction Insert With Placeholders: 0.71131205558777
Time Spent for transaction: 8.0056409835815
Time Spent for AutoCommit: 35.4979159832
Time Spent for autocommit with bind: 33.303519010544

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接