Mysqli multiple row insert, simple multi insert query [duplicate]

The mysqli class provides a number of different ways of accomplishing your inserts, each with its own benefits. Certainly, one of them should fit your needs.

The following examples assume that your unspecified “extracted data” is stored in an array of arrays: $bigArray[0…datasetsize][0…2].

The mysqli database is assumed to be $db.

Method 1 – As Simple As Possible

If you want to use a prepared statement and parameter binding, a first effort might look like the following. While not optimal, the statement is only prepared once. However, the variables are bound for each insert, which is wasteful (but simple). Since inserts are not bundled, the example loops over 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();
}

Method 2 – Optimized

Prepared statements and multiple inserts combined enable performance which is nearly identical to the raw insert queries of Method 1. Actual results will vary depending on your setup, but a quick test on my system with both a local and a remote database showed performance a few percentage points faster with the optimized method, increasing a few points more if data in Method 1 needs to be escaped.

The following uses call_user_func_array, but you could avoid that if you know how many inserts you want to bundle each time and build call bind_param directly. That would further increase performance slightly.

$sql = "INSERT INTO testTable (fieldA,fieldB,fieldC) VALUES (?,?,?)".str_repeat(",(?,?,?)",count($bigArray)-1);
$statement = $db->prepare($sql);

// This is the type string used by statement::bind_param. 
// s will be good for any type.
$types = str_repeat("s", count($bigArray) * count($bigArray[0]));

$values = array_merge(...$bigArray);
$statement->bind_param($types, ...$values);
$statement->execute();

Leave a Comment