Делайте это партиями, например, 1000 строк одновременно.
Используйте PDO вместо mysqli, так как он позволяет вам выполнить подготовленный оператор с массивом для предоставления значений.
$batch_size = 1000;
$sql = "INSERT INTO book(firstname, lastname, phone_number, address) VALUES ";
// Add 1,000 value lists
$sql .= str_repeat("(?,?,?,?),", $batch_size-1);
$sql .= "(?,?,?,?),";
$stmt = $pdo->prepare($sql);
for ($i = 0; $i < (1000000/$batch_size); $i++) {
$vals = array();
for ($j = 0; $j < $batch_size; $j++) {
array_push($vals, "name$j", "address$j", mt_rand(), "address" . mt_rand());
}
$stmt->execute($vals);
}
Возможно, вам потребуется увеличить параметр max_allowed_packet
сервера MySQL для обработки 1000 строк или уменьшить размер пакета. Убедитесь, что $batch_size
равномерно делится на 1 миллион - приведенный выше код не обрабатывает последнюю партию не того же размера (рассмотрите возможность исправить это как упражнение для читателя).