我需要测试一些大型数据集(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 :(得分:0)
您可以使用https://github.com/fzaninotto/Faker。您可以根据需要制作循环并伪造尽可能多的记录。全部都是随机数据。
答案 1 :(得分: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 versus InnoDB