mysqli クラスは、挿入を実行するさまざまな方法を提供し、それぞれに独自の利点があります。確かに、そのうちの 1 つがニーズに合うはずです。
次の例では、指定されていない「抽出されたデータ」が配列の配列に格納されていると想定しています: $bigArray[0...datasetsize][0...2]。
mysqli データベースは $db であると想定されます。
方法 1 - オールドスクール
クエリ文字列を作成し、それを使用してデータベースにクエリを実行するだけで、慣れているように簡単に実行できます。ご指定のとおり、インサートは一度に10個同梱されます。次のコードは、そのようなバンドルの 1 つを示しており、データ セット全体 (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 - できるだけ簡単に
プリペアド ステートメントとパラメーター バインディングを使用する場合、最初の作業は次のようになります。最適ではありませんが、ステートメントは 1 回だけ準備されます。ただし、変数は挿入ごとにバインドされるため、無駄です (ただし単純です)。挿入はバンドルされていないため、この例は 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()).