【发布时间】:2010-12-02 19:18:27
【问题描述】:
我在 mysqld 中看到了我不理解的性能行为。
我有一个表 t,它有一个主键 id 和三个数据列 col1,... col4。
数据在 4 个 TSV 文件 'col1.tsv', ... 'col4.tsv' 中。我用来摄取它们的过程是:
CREATE TABLE t (
id INT NOT NULL,
col1 INT NOT NULL,
col2 INT NOT NULL,
col3 INT NOT NULL,
col4 CHAR(12) CHARACTER SET latin1 NOT NULL );
LOAD DATA LOCAL INFILE # POP 1
'col1.tsv' INTO TABLE t (id, col1);
ALTER TABLE t ADD PRIMARY KEY (id);
SET GLOBAL hot_keys.key_buffer_size= # something suitable
CACHE INDEX t IN hot_keys;
LOAD INDEX INTO CACHE t;
DROP TABLE IF EXISTS tmpt;
CREATE TABLE tmpt ( id INT NOT NULL, val INT NOT NULL );
LOAD DATA LOCAL INFILE 'col2.tsv' INTO TABLE tmpt tt;
INSERT INTO t (id, col2) # POP 2
SELECT tt.id, tt.val FROM tmpt tt
ON DUPLICATE KEY UPDATE col2=tt.val;
DROP TABLE IF EXISTS tmpt;
CREATE TABLE tmpt ( id INT NOT NULL, val INT NOT NULL );
LOAD DATA LOCAL INFILE 'col3.tsv' INTO TABLE tmpt tt;
INSERT INTO t (id, col3) # POP 3
SELECT tt.id, tt.val FROM tmpt tt
ON DUPLICATE KEY UPDATE col3=tt.val;
DROP TABLE IF EXISTS tmpt;
CREATE TABLE tmpt ( id INT NOT NULL,
val CHAR(12) CHARACTER SET latin1 NOT NULL );
LOAD DATA LOCAL INFILE 'col4.tsv' INTO TABLE tmpt tt;
INSERT INTO t (id, col4) # POP 4
SELECT tt.id, tt.val FROM tmpt tt
ON DUPLICATE KEY UPDATE col4=tt.val;
现在这是我不明白的性能问题。有时 POP 2 和 3 INSERT INTO ... SELECT ... ON DUPLICATE KEY UPDATE 查询使用 mysqld 运行得非常快 占用 100% 的核心,而在其他时间 mysqld 以 1% 的 CPU 读取 t.MYD,即表 t 的 MyISAM 数据文件,以随机偏移量陷入困境。
我很难确定在哪些情况下它是快速和 虽然速度很慢,但我发现了一个可重复的案例:
在上述序列中,POP 2 和 3 非常慢。但是,如果我创建 t 没有 col4 则 POP 2 和 POP 3 非常快。为什么?
如果在那之后,我用 ALTER TABLE 查询添加 col4,然后 POP 4 运行 也很快。
同样,当 INSERT 运行缓慢时,mysqld 陷入文件 IO 中 从表 t 的 MyISAM 数据文件中读取随机偏移量。我什至不 了解它为什么要读取该文件。
MySQL 服务器版本 5.0.87。 Core 2 Duo iMac 上的 OS X 10.6.4。
更新
我最终找到了(我认为是)这个问题的答案。一些插入慢和一些快之间的神秘差异取决于数据。
线索是:当插入速度很慢时,mysqld 在 t.MYD 上的读取之间平均寻找 0.5GB。速度快时,连续读取的相对偏移量很小。
之所以出现混淆,是因为某些“col?.tsv”文件的行恰好与 w.r.t 的顺序大致相同。 id 列,而其他列相对于它们随机排序。
通过在加载和插入 tsv 文件之前使用 sort(1),我能够大大减少整体处理时间。
【问题讨论】:
-
你想做什么 - 请直接回答!!
-
它正在读取该文件,因为您正在插入该文件?
-
@f00:我正在尝试将 TSV 文件摄取到表中,如 OP 的第二和第三句中所述。
-
@Danosaure:看起来是这样。在 POP 2 INSERT 的前半小时左右,所有磁盘 IO 都是(随机偏移)从我要插入的表的数据文件中读取的。几个小时后,它是读取和写入的混合体。
-
@fsb:也许不相关......但我看到我的生产服务器在 MySQL 5.0.x 上运行的双 CPU 64 位比单 CPU 少 32 位 RAM 慢(具有相同的在 my.cnf 中设置)。 5.1.x 不会发生这种情况您是否可以在另一台服务器上尝试此操作以查看是否发生相同的模式?
标签: mysql performance optimization