背景:我有一个固定宽度的平面文件,大约有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方法?如果有,我想将这些信息传递给使用这些数据的未来研究人员。
答案 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,除非你在客户。