【发布时间】:2013-06-12 18:17:07
【问题描述】:
我正在一个 MySQL 服务器中测试性能并填充一个包含超过 2 亿条记录的表。存储过程生成大 SQL 字符串的速度非常慢。非常欢迎任何帮助或评论。
系统信息:
- 数据库: MySQL 5.6.10 InnoDB 数据库(测试)。
- 处理器: AMD Phenom II 1090T X6 内核,每个内核 3910Mhz。
- 内存: 16GB DDR3 1600Mhz CL8。
- HD: SSD 中的 Windows 7 64 位 SP1,SSD 中安装的 mySQL,机械硬盘中写入的日志。
存储过程创建一个 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);
结果(按持续时间排序) - 以秒为单位的状态(总和)||百分比
释放物品 0.00005 50.00000
起始 0.00002 20.00000
执行 0.00001 10.00000
初始化 0.00001 10.00000
清理 0.00001 10.00000
总计 0.00010 100.00000
由于执行查询导致状态变量的变化
变量值说明
Bytes_received 21 字节从客户端发送到服务器
Bytes_sent 97 字节从服务器发送到客户端
Com_select 1 已执行的 SELECT 语句数
问题 1 服务器执行的语句数
测试:
我已经测试了从 12 到 64 线程的不同 MySQL 配置,打开和关闭缓存,将日志移动到另一个硬件磁盘...
还使用 TEXT、INT.. 进行了测试。
其他信息:
- 性能链接:general&multiple-cores、configuration、optimizing IO、Debiancores、best configuration、config 48gb ram..
- 分析 SQL 查询:How to profile a query、Check for possible bottleneck in a query
问题:
- 代码有问题吗?如果我发送 100000 个字符串来构建最终的 SQL 字符串,则
SELECT squery;的结果是一个 NULL 字符串。发生了什么? (一定有错误,但我没有看到)。 - 我可以通过任何方式改进代码以加快速度吗?
- 我已经阅读了存储过程中的一些操作可能真的很慢,我应该在 C/Java/PHP.. 和send it to mysql 中生成文件吗?
mysql -u mysqluser -p 数据库名
- MySQL 似乎对use only one core for one single SQL query、nginx 或其他数据库系统:Multithreadted DBs、Cassandra、Redis、MongoDB..) 通过存储过程实现更好的性能并使用多个 CPU 来实现一个查询? (因为我的单个查询只使用了大约 150 个线程的总 CPU 的 20%)。
更新:
【问题讨论】:
-
一条评论!为什么以 Cthulhu 的名义,您使用 DBMS 循环数次以连接字符串。没想到居然这么快,你在这里检查礼物马的牙齿。
-
这可能是我在这里遇到的信息量最大的问题,好极了
-
嗨托尼霍普金森,我试图在这里提供帮助 stackoverflow.com/questions/17042760/… 并试图用大量随机数据快速填充表格以检查性能并使用数百万数据进行一些测试,当我发现了这个问题。
标签: mysql database multithreading stored-procedures concat