mysqli 类提供了许多不同的方法来完成您的插入,每种方法都有自己的优点。当然,其中之一应该适合您的需求。
以下示例假定您未指定的“提取数据”存储在数组数组中:$bigArray[0...datasetsize][0...2]。
mysqli 数据库假定为 $db。
方法 1 - 老派
您可以像以前那样直接构建查询字符串并使用它查询数据库。正如您指定的那样,插件一次捆绑 10 个。以下代码显示了一个这样的捆绑包,并被简单地扩展到整个数据集 (bigArray)。数据可能应该使用 mysqli::escape_string 进行转义(此处未完成)。
在所有示例中,要插入的数据都假定为整数。
$sql = "INSERT INTO testTable (fieldA, fieldB, fieldC) VALUES ";
for ($i = 0; $i < 10; ++$i)
{
if ($i > 0) $sql .= ", ";
$sql .= "({$bigArray[$i][0]}),({$bigArray[$i][1]}),({$bigArray[$i][2]})";
}
$db->query($sql);
方法 2 - 尽可能简单
如果您想使用准备好的语句和参数绑定,第一次尝试可能如下所示。虽然不是最优的,但该语句只准备一次。但是,变量是为每个插入绑定的,这很浪费(但很简单)。由于未捆绑插入,因此示例循环超过 10 个。
$statement = $db->prepare("INSERT INTO testTable (fieldA, fieldB, fieldC) VALUES (?,?,?)");
for ($i = 0; $i < 10; ++$i)
{
$statement->bind_param("iii",$bigArray[$i][0],$bigArray[$i][1],$bigArray[$i][2]);
$statement->execute();
}
方法 3 - 优化
准备好的语句和多个插入组合使性能几乎与方法 1 的原始插入查询相同。实际结果会因您的设置而异,但在我的系统上使用本地和远程数据库进行的快速测试显示性能只有几个百分比使用优化的方法更快点,如果需要转义方法 1 中的数据,则增加几个点。
以下使用 call_user_func_array,但如果您知道每次要捆绑多少插入并直接构建调用 bind_param,则可以避免这种情况。这将进一步略微提高性能。
为清楚起见,此示例包括外部循环并假设要插入总共 10k 行(即 bigArray[0..9999][0..2])。
$sql = "INSERT INTO testTable (fieldA,fieldB,fieldC) VALUES (?,?,?)".str_repeat(",(?,?,?)",9);
$statement = $db->prepare($sql);
// This is the type string used by statement::bind_param.
// Example assumes all INTs.
$types = (array)str_repeat("i",30);
$values = array_fill(0,30,0); // A bit of unneeded variable init.
// * See notes following code snippet on why the intermediate array is used.
$intermediate = array();
for ($n = 0; $n < 30; ++$n)
{
$intermediate[$n] = &$values[$n];
}
call_user_func_array(array(&$statement, "bind_param"), array_merge($types,$f));
for ($j = 0; $j < 1000; ++$j)
{
for ($i = 0; $i < 10; ++$i)
{
$values[$i*3] = $bigArray[$i][0];
$values[$i*3+1] = $bigArray[$i][1];
$values[$i*3+2] = $bigArray[$i][2];
}
$statement->execute();
}
// call_user_func_array with bind_param requires the values be
// passed by reference which is evaluated only on the initial
// call. Using $values[...] = &$bigArray[...] below won't work
// and an intermediate array referencing $values is used. This
// bit of "extra funky stuff" can be avoided at a very slight
// performance penalty by setting $values[...] = $bigArray[...]
// AND EVALUATING EACH TIME (move call_user_func_array
// inside the outer loop, i.e. right above $statement->execute()).