Создание пакетного сценария вставки MySQL для фиктивных данных

Мне нужно протестировать некоторые запросы на больших наборах данных (1M - 50M) например, и у меня возникают проблемы при написании процесса, который будет делать это быстро.

У меня есть код ниже, который немного изменен по сравнению с версией, которую я нашел в другом посте SO:

set_time_limit(0);

$db_host = 'localhost';
$db_name = 'test';

$db_user = '';
$db_pass = '';

$entries = 1000000;
$entry_words_min = 250;
$entry_words_max = 1000;

/*
End configuration
*/

function get_rand_word( $len_min, $len_max ) {
for ( $i = 0; $i < ( rand( 0, $len_max - $len_min ) + $len_min ); $i++ ) {
$word .= chr(rand(65, 90));
}
return $word;
}
function get_title() {
for ( $i = 0; $i < ( rand( 4, 10 ) ); $i++ ) {
$title .= get_rand_word( 2, 9 ) . ' ';
}
return $title;
}
function get_fulltext() {
for ( $i = 0; $i < ( rand( 250, 500 ) ); $i++ ) {
$fulltext .= get_rand_word( 2, 9 ) . ' ';
}
return $fulltext;
}

$dsn = 'mysql:dbname=' . $db_name . ';host=' . $db_host;

try {
$dbh = new PDO($dsn, $db_user, $db_pass);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
die();
}

$sth = $dbh->prepare('INSERT INTO `sphinx` (`some_id`,`title`,`content`) VALUES (:some_id, :title, :content)');

$counter = 0;

for ( $i = 0; $i < $entries; $i++ ) {
$sth->execute(array(
':some_id' => mt_rand(1,65000),
':title' => get_title(),
':content' => get_fulltext()
));
$counter++;
}

echo $counter . ' rows inserted';

Однако это довольно медленно при вставке; потребовалось несколько часов, чтобы вставить 500k строк. Я знаю, что мог бы написать запрос на пакетную вставку, но я не думаю, что это хорошая идея написать один запрос на миллион вставок; Я думаю, что это может быть разбито на 10k время или что-то, но хотел проверить, есть ли какие-либо более лучшие / более чистые доступные методы.

0

Решение

Вы могли бы использовать https://github.com/fzaninotto/Faker. Вы можете сделать цикл и подделать столько записей, сколько вам нужно. Все со случайными данными.

0

Другие решения

Прежде всего, я предлагаю измерить время, после n-й вставки, скажем, каждые 10000 циклов, чтобы увидеть любые аномалии.

$start = microtime(true);
for ($i = 0; $i < $entries; $i++) {
$sth->execute(array(
':some_id' => mt_rand(1,65000),
':title' => get_title(),
':content' => get_fulltext()
));
if ($i % 10000 === 9999) {
$end = microtime(true);
echo $i . ' ' . ($end - $start) . '<br>';
}
$counter++;
}

Также могут быть проблемы с типом базы данных или индексами или даже с жестким диском. Сравнение наиболее известных типов:
MyISAM против InnoDB

0