当行具有值'x'时,在MySQL LOAD DATA INFILE语句中跳过行

时间:2011-10-24 19:25:39

标签: mysql database data-warehouse

背景:我有一个固定宽度的平面文件,大约有9400万行数据。该文件来自HCUP Nationwide住院患者样本(NIS http://www.hcup-us.ahrq.gov/nisoverview.jsp),该样本提供过去12年内住院治疗的信息,每一行都是单独的住院治疗。对于我的分析,我将查询诊断代码(ICD9-CM)以识别具有各种诊断的患者。

固定宽度文件包含最多15个诊断代码的信息,这些代码以列dx1到dx15的形式提供。

create table `core` (`key` char (14),
`dx1` char (5),
`dx10` char (5),
`dx11` char (5),
`dx12` char (5),
`dx13` char (5),
`dx14` char (5),
`dx15` char (5),
`dx19` char (5),
`dx2` char (5),
`dx3` char (5),
`dx4` char (5),
`dx5` char (5),
`dx6` char (5),
`dx7` char (5),
`dx8` char (5),
`dx9` char (5),
plus various other columns of patient demographics...);

我将所有数据加载到名为core的MySQL表中,并且可以索引15列。但是,将dx *列规范化为单独的dx表似乎是有利的,例如;

create table `dx` (
`key` char (14),
`icd9` char (5),
);

其中key是主core表的外键。要快速将数据加载到dx,我使用:

LOAD DATA LOCAL INFILE 'data.ASC' INTO TABLE `dx` (@var1) SET `key` = substr(@var1, 1, 14), `icd9` = substr(@var1, 74, 5);
LOAD DATA LOCAL INFILE 'data.ASC' INTO TABLE `dx` (@var1) SET `key` = substr(@var1, 1, 14), `icd9` = substr(@var1, 79, 5);
LOAD DATA LOCAL INFILE 'data.ASC' INTO TABLE `dx` (@var1) SET `key` = substr(@var1, 1, 14), `icd9` = substr(@var1, 84, 5);
etc for all 15 columns...

问题是固定宽度文件中的每一行只有3个诊断代码的中位数,因此大多数dx *列只是空白(' ' [五个空白字符])。因此,虽然dx表在加载数据后有14.1亿(9400万* 15)行,但大约有12.8亿(9400万* 12)是空白诊断代码。

我之前只是在索引之前删除它们并进行优化:

DELETE FROM `dx` WHERE `icd9` = "     ";
OPTIMIZE TABLE `dx`;
CREATE INDEX `icd9` ON `dx` (`icd9`);

但是,这需要花费很多时间。

问题:如果ICD9 = ' ' [五个空白字符],是否可以修改LOAD DATA INFILE语句以跳过该行,这会明显加快比我目前的DELETE和OPTIMIZE方法?如果有,我想将这些信息传递给使用这些数据的未来研究人员。

2 个答案:

答案 0 :(得分:1)

  

是否可以修改LOAD DATA INFILE语句以跳过   行如果

没有。有一个IGNORE选项。但是,它使用的行号不是内联逻辑比较。

  

这会比我目前的DELETE和OPTIMIZE快得多   方法

可能的。但是,因为它不是一种选择,所以无所谓。

答案 1 :(得分:1)

我想,如果您可以在诊断代码上使用唯一键,请说出密钥dc(c1,c2,c3) 并使用加载数据infile file_name ignore into table选项,将忽略所有唯一的密钥重复项。 因此,您只剩下一个代码组合,即'','',''。一切 休息将被忽略。 但是,这显然比简单的infile消耗更多的资源,但应该比之后删除更快。 另外,我认为如果你的所有诊断代码都是int可能会更好,这会为空白存储'0',并且当有重复的条目尝试时,mysql应该更快地识别整数而不是字符串。< / p>

我还建议你不要使用'本地'infile,除非你在客户。