我正在测试MySQL服务器中的性能并填充一个包含超过 2 亿条记录的表。存储过程生成大 SQL 字符串的速度非常慢。非常欢迎任何帮助或评论。
系统信息:
- 数据库: MySQL 5.6.10 InnoDB 数据库(测试)。
- 处理器: AMD Phenom II 1090T X6 核心,每个核心 3910Mhz。
- 内存: 16GB DDR3 1600Mhz CL8。
- HD: Windows 7 64bits SP1 in SSD,mySQL 安装在 SSD,日志写入机械硬盘。
存储过程创建一个 INSERT sql 查询,其中包含要插入到表中的所有值。
DELIMITER $$
USE `test`$$
DROP PROCEDURE IF EXISTS `inputRowsNoRandom`$$
CREATE DEFINER=`root`@`localhost` PROCEDURE `inputRowsNoRandom`(IN NumRows BIGINT)
BEGIN
/* BUILD INSERT SENTENCE WITH A LOS OF ROWS TO INSERT */
DECLARE i BIGINT;
DECLARE nMax BIGINT;
DECLARE squery LONGTEXT;
DECLARE svalues LONGTEXT;
SET i = 1;
SET nMax = NumRows + 1;
SET squery = 'INSERT INTO `entity_versionable` (fk_entity, str1, str2, bool1, double1, DATE) VALUES ';
SET svalues = '("1", "a1", 100, 1, 500000, "2013-06-14 12:40:45"),';
WHILE i < nMax DO
SET squery = CONCAT(squery, svalues);
SET i = i + 1;
END WHILE;
/*SELECT squery;*/
SET squery = LEFT(squery, CHAR_LENGTH(squery) - 1);
SET squery = CONCAT(squery, ";");
SELECT squery;
/* EXECUTE INSERT SENTENCE */
/*START TRANSACTION;*/
/*PREPARE stmt FROM squery;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
*/
/*COMMIT;*/
END$$
DELIMITER ;
结果:
- 连接 20000 个字符串大约需要 45 秒来处理:
调用 test.inputRowsNoRandom(20000);
- 连接 100000 个字符串大约需要 +5/12 分钟 O_O:
调用 test.inputRowsNoRandom(100000);
结果(按持续时间排序) - 以秒为单位的状态(总和)|| percentage
freeing
items 0.00005
50.00000 starting 0.00002 20.00000
executing 0.00001 10.00000
init 0.00001 10.00000
cleaning up 0.00001 10.00000
Total 0.00010 100.00000
Change Of STATUS VARIABLES Due To Execution Of Query
variable value description
Bytes_received 21 Bytes sent from the client to the server
Bytes_sent 97 Bytes sent from the server到客户端
Com_select 1 已执行的 SELECT 语句
数 Questions 1 服务器执行的语句数
测试:
我已经测试了从 12 到 64 线程的不同 MySQL 配置,设置缓存打开和关闭,将日志移动到另一个硬件磁盘......
还使用 TEXT、INT 进行了测试。
附加信息:
- 性能链接:general&multiple-cores , configuration , optimization IO , Debiancores , best configuration , config 48gb ram ..
- 分析 SQL 查询:如何分析查询,检查查询中可能存在的瓶颈
问题:
- 代码有问题吗?如果我发送 100000 个字符串来构建最终的 SQL 字符串,则结果
SELECT squery;
是 NULL 字符串。发生了什么?(错误必须存在,但我没有看到)。 - 我可以以任何方式改进代码以加快速度吗?
- 我已经阅读了存储过程中的一些操作可能真的很慢,我应该在 C/Java/PHP 中生成文件并将其发送到 mysql吗?
mysql -u mysqluser -p 数据库名<numbers.sql
- MySQL 似乎只为一个 SQL 查询使用一个内核,nginx或其他数据库系统:多线程数据库、Cassandra、Redis、MongoDB ..) 是否可以通过存储过程实现更好的性能,并为一个查询使用多个 CPU?(因为我的单个查询只使用了大约 150 个线程的总 CPU 的 20%)。
更新:
- 填写表格的有效方式,请查看下面的peterm答案。
- 存储过程、现代 RDBMS 或内联查询的性能。