我有一个分区的InnoDB mysql表,我需要插入数亿行。
我目前正在使用LOAD DATA INFILE
命令将许多(想到成千上万的).csv文件加载到所述表中。
如果我同时将大块数据插入不同的不同分区,会对性能产生什么影响?
我可以通过运行多个流程来获益,每个流程都会运行批量LOAD DATA INFILE
个语句吗?
其他信息:
硬件:Intel i7,24GB内存,Ubuntu 10.04 w / MySQL 5.5.11,Raid 1存储
freenode上的#mysql IRC告诉我,性能影响与普通的InnoDB或MyISAM相同 - InnoDB将进行行级锁定,MyISAM将进行表级锁定。表格结构:
CREATE TABLE `my_table` (
`short_name` varchar(10) NOT NULL,
`specific_info` varchar(20) NOT NULL,
`date_of_inquiry` datetime DEFAULT NULL,
`price_paid` decimal(8,2) DEFAULT NULL,
`details` varchar(255) DEFAULT '',
UNIQUE KEY `unique_record` (`short_name`,`specific_info`,`date_of_inquiry`),
KEY `short_name` (`short_name`),
KEY `underlying_quotedate` (`short_name`,`date_of_inquiry`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
/*!50500 PARTITION BY LIST COLUMNS(short_name)*/
(PARTITION pTOYS_R_US VALUES IN ('TOYS-R-US') ENGINE = InnoDB,
PARTITION pZAPPOS VALUES IN ('ZAPPOS') ENGINE = InnoDB,
PARTITION pDC VALUES IN ('DC') ENGINE = InnoDB,
PARTITION pGUCCI VALUES IN ('GUCCI') ENGINE = InnoDB,
...on and on...
);
答案 0 :(得分:2)
不是完整的清单,而是一些指示......
插入行的最快方法是使用LOAD DATA INFILE
请参阅:http://dev.mysql.com/doc/refman/5.1/en/load-data.html
如果这不是一个选项,并且你想加快速度,你需要找到瓶颈并对其进行优化。
如果分区是通过网络进行的,那么网络流量可能会因CPU,磁盘I / O和内存而导致死亡,只有分析样本才能说明。
禁用密钥更新
如果您无法load data infile
确保禁用密钥更新
ALTER TABLE table1 DISABLE KEYS
... lots of inserts
ALTER TABLE table1 ENABLE KEYS
请注意disable key updates
仅禁用非唯一键,唯一键始终更新。
二进制日志
如果您运行二进制日志,这将记录所有这些插入,考虑禁用它,您可以通过使用符号链接运行MySQL并在质量插入的持续时间指向/dev/null
来禁用它。
如果希望二进制日志保持不变,则可以同时插入具有blackhole
表并启用二进制日志的并行数据库。
自动增量键
如果你让MySQL计算自动增量密钥,这将在密钥生成周围产生争用。考虑向MySQL提供预先计算的自动递增的primay键值而不是NULL
唯一键
每个插入(唯一性)都会检查唯一键,它们会占用大量时间。因为MySQL需要对每个插入的索引进行全面扫描
如果您知道所插入的值是唯一的,那么最好放弃该要求并在完成后添加它
当你在MySQL中添加它时需要花费大量的时间进行检查,但至少它只会执行一次,而不是每次插入。
答案 1 :(得分:0)
如果您希望从中获得最大的I / O性能,您将需要不同磁盘卷上的不同分区。
如果所有分区都位于相同的物理磁盘上,我不确定性能影响,但显然你更有可能以这种方式耗尽I / O容量。
答案 2 :(得分:0)
这可能取决于你的机器规格,但是为了它的价值,我已经尝试了这一点,它肯定会加速我的具体任务。即,将所有数据加载到一个分区需要大约一个小时。如果我不进行分区,我必须按顺序执行任务,因此需要12 * 1 = 12小时。但是,在我的24核心机器上,我可以在1小时内完成任务的并行化。