我需要加载一个包含大量测试数据的表。这将用于测试性能和扩展。
如何为数据库表轻松创建100,000行随机/垃圾数据?
答案 0 :(得分:72)
您还可以使用stored procedure。以下表为例:
CREATE TABLE your_table (id int NOT NULL PRIMARY KEY AUTO_INCREMENT, val int);
然后你可以像这样添加一个存储过程:
DELIMITER $$
CREATE PROCEDURE prepare_data()
BEGIN
DECLARE i INT DEFAULT 100;
WHILE i < 100000 DO
INSERT INTO your_table (val) VALUES (i);
SET i = i + 1;
END WHILE;
END$$
DELIMITER ;
当你打电话时,你将拥有100k记录:
CALL prepare_data();
答案 1 :(得分:14)
对于多行克隆(数据复制),您可以使用
DELIMITER $$
CREATE PROCEDURE insert_test_data()
BEGIN
DECLARE i INT DEFAULT 1;
WHILE i < 100000 DO
INSERT INTO `table` (`user_id`, `page_id`, `name`, `description`, `created`)
SELECT `user_id`, `page_id`, `name`, `description`, `created`
FROM `table`
WHERE id = 1;
SET i = i + 1;
END WHILE;
END$$
DELIMITER ;
CALL insert_test_data();
DROP PROCEDURE insert_test_data;
答案 2 :(得分:4)
如果您想要更多地控制数据,请尝试这样的事情(在PHP中):
<?php
$conn = mysql_connect(...);
$num = 100000;
$sql = 'INSERT INTO `table` (`col1`, `col2`, ...) VALUES ';
for ($i = 0; $i < $num; $i++) {
mysql_query($sql . generate_test_values($i));
}
?>
其中function generate_test_values将返回格式为“('val1','val2',...)”的字符串。如果这需要很长时间,您可以对它们进行批处理,这样您就不会进行如此多的数据库调用,例如:
for ($i = 0; $i < $num; $i += 10) {
$values = array();
for ($j = 0; $j < 10; $j++) {
$values[] = generate_test_data($i + $j);
}
mysql_query($sql . join(", ", $values));
}
只会运行10000个查询,每个查询会添加10行。
答案 3 :(得分:4)
这是纯数学和sql的解决方案:
create table t1(x int primary key auto_increment);
insert into t1 () values (),(),();
mysql> insert into t1 (x) select x + (select count(*) from t1) from t1;
Query OK, 1265 rows affected (0.01 sec)
Records: 1265 Duplicates: 0 Warnings: 0
mysql> insert into t1 (x) select x + (select count(*) from t1) from t1;
Query OK, 2530 rows affected (0.02 sec)
Records: 2530 Duplicates: 0 Warnings: 0
mysql> insert into t1 (x) select x + (select count(*) from t1) from t1;
Query OK, 5060 rows affected (0.03 sec)
Records: 5060 Duplicates: 0 Warnings: 0
mysql> insert into t1 (x) select x + (select count(*) from t1) from t1;
Query OK, 10120 rows affected (0.05 sec)
Records: 10120 Duplicates: 0 Warnings: 0
mysql> insert into t1 (x) select x + (select count(*) from t1) from t1;
Query OK, 20240 rows affected (0.12 sec)
Records: 20240 Duplicates: 0 Warnings: 0
mysql> insert into t1 (x) select x + (select count(*) from t1) from t1;
Query OK, 40480 rows affected (0.17 sec)
Records: 40480 Duplicates: 0 Warnings: 0
mysql> insert into t1 (x) select x + (select count(*) from t1) from t1;
Query OK, 80960 rows affected (0.31 sec)
Records: 80960 Duplicates: 0 Warnings: 0
mysql> insert into t1 (x) select x + (select count(*) from t1) from t1;
Query OK, 161920 rows affected (0.57 sec)
Records: 161920 Duplicates: 0 Warnings: 0
mysql> insert into t1 (x) select x + (select count(*) from t1) from t1;
Query OK, 323840 rows affected (1.13 sec)
Records: 323840 Duplicates: 0 Warnings: 0
mysql> insert into t1 (x) select x + (select count(*) from t1) from t1;
Query OK, 647680 rows affected (2.33 sec)
Records: 647680 Duplicates: 0 Warnings: 0
答案 4 :(得分:1)
我真的很喜欢Percona的mysql_random_data_loader实用工具,您可以在here中找到有关它的更多详细信息。
mysql_random_data_loader是连接到mysql数据库并使用随机数据填充指定表的实用程序。如果表中存在外键,则它们也将正确填充。
此实用程序具有很酷的功能,可以限制数据生成的速度。
例如,要以每秒500条记录的速度在sakila.film_actor表中生成30,000条记录,您需要以下命令
mysql_random_data_load sakila film_actor 30000 --host=127.0.0.1 --port=3306 --user=my_user --password=my_password --qps=500 --bulk-size=1
通过在不同的表上以不同的速度在多个线程上运行此实用程序,我已经成功地使用了该工具在测试环境中模拟工作负载。
答案 5 :(得分:0)
我创建了一个ruby脚本,该脚本可以插入几乎没有表之间的外键验证的“任何”数据库中,并且可以插入随机数据,因此您可以对其中的一些数据进行基准测试。 稍后(如果有空闲时间),我将通过此GIST创建一个gem-> https://gist.github.com/carlosveucv/137ea32892ef96ab496def5fcd21858b
答案 6 :(得分:0)
尝试filldb
您可以发布架构或使用现有架构并生成虚拟数据,然后从该站点导出并导入数据库。
答案 7 :(得分:0)
create table mydata as select * from information_schema.columns;
insert into mydata select * from mydata;
-- repeating the insert 11 times will give you at least 6 mln rows in the table.
答案 8 :(得分:0)
这是对@michalzuber 回答的更高效的修改。唯一的区别是删除了 WHERE id = 1
,这样每次运行时插入都可以累积。
产生的记录数量为 n^2;
所以对于 10 次迭代,10^2 = 1024 条记录 对于 20 次迭代,20^2 = 1048576 条记录,依此类推。
DELIMITER $$
CREATE PROCEDURE insert_test_data()
BEGIN
DECLARE i INT DEFAULT 1;
WHILE i <= 10 DO
INSERT INTO `table` (`user_id`, `page_id`, `name`, `description`, `created`)
SELECT `user_id`, `page_id`, `name`, `description`, `created`
FROM `table`;
SET i = i + 1;
END WHILE;
END$$
DELIMITER ;
CALL insert_test_data();
DROP PROCEDURE insert_test_data;