1

I`m looking for php script to generate random data and insert 1 million rows into the mysql database.

It`s a test case i received as part of my homework.

Here is a piece of code i`ve tried but it didnt work as the allowed memory size exhausted.

P.S. Cant change memory_limit as it`s prohibited and counts as cheating :)

$query = "INSERT INTO book(firstname, lastname, phone_number, address) VALUES ";
   $query_parts = array();
   for($i=0; $i<1000000; $i++){
     $firstname = 'name' . $i;
     $lastname = 'lastname' . $i;
     $phone_number = mt_rand();
     $address = 'address' . mt_rand();
     $query_parts[] = "('" . $firstname . "', '" . $lastname . "', '" . $phone_number . "', '" . $address . "')";
   }
   $query .= implode(',', $query_parts);

   $create_record_query = mysqli_query($connection, $query);
7
  • Weird, who gives you such kinda conditions? Commented Apr 23, 2019 at 20:58
  • Do them in batches of a thousand at a time. You also need to take the MySQL max_allowed_packet setting into account. Commented Apr 23, 2019 at 20:59
  • 3
    Can you write the data to a file and then use LOAD DATA INFILE? Commented Apr 23, 2019 at 20:59
  • You will need to chunk the data into smaller requests and process. This is actually a pretty common when handling large amounts of data. @Barmar If that is allowed I agree that is definitely the best solution. Commented Apr 23, 2019 at 21:13
  • 1
    Can you use PDO instead of mysqli? It's easier to create a PDO prepared statement with a thousands ? and put all the values in an array. Commented Apr 23, 2019 at 21:18

1 Answer 1

1

Do it in batches, e.g. 1000 rows at a time.

Use PDO rather than mysqli, as it allows you to execute a prepared statement with an array to supply the values.

$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);
}

You might need to increase the MySQL server's max_allowed_packet setting to handle 1000 rows, or decrease the batch size. Make sure that $batch_size evenly divides into 1 million -- the code above doesn't handle a last batch that's not the same size (consider fixing that as an exercise for the reader).

Sign up to request clarification or add additional context in comments.

1 Comment

$sql .= "(?,?,?,?),"; is supposed to be $sql .= "(?,?,?,?)";

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.