在数据导入期间永远不会结束MySQL查询

时间:2013-03-07 21:04:23

标签: mysql

我正在处理从一组CSV文件到我的主数据库的数据导入例程,并且我遇到了这个特定的数据集。我使用LOAD DATA LOCAL INFILE将CSV数据转储到我的表中,feed_hcp_leasenote:

CREATE TABLE `feed_hcp_leasenote` (
 `BLDGID` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
 `LEASID` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
 `NOTEDATE` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
 `REF1` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
 `REF2` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
 `LASTDATE` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
 `USERID` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
 `NOTETEXT` varchar(1000) COLLATE utf8_unicode_ci DEFAULT NULL,
 `tempid` int(11) NOT NULL AUTO_INCREMENT,
 PRIMARY KEY (`tempid`),
 KEY `BLDGID` (`BLDGID`),
 KEY `LEASID` (`LEASID`),
 KEY `REF1` (`REF1`),
 KEY `NOTEDATE` (`NOTEDATE`)
) ENGINE=MyISAM AUTO_INCREMENT=65002 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

我正在尝试将这些数据导入两个表,lease_notes和customfield_data。 lease_notes仅存储唯一的ID值,注释本身以及将其链接到租赁表的盖子。 customfield_data存储系统和用户创建的字段的各种数据,每个记录通过linkid字段链接到另一个表。这是lease_note表:

CREATE TABLE `lease_notes` (
 `lnid` int(11) NOT NULL AUTO_INCREMENT,
 `notetext` longtext COLLATE utf8_unicode_ci NOT NULL,
 `lid` int(11) NOT NULL COMMENT 'Lease ID',
 PRIMARY KEY (`lnid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

customfield_data表:

CREATE TABLE `customfield_data` (
 `cfdid` int(11) NOT NULL AUTO_INCREMENT,
 `data_int` int(11) DEFAULT NULL,
 `data_date` datetime DEFAULT NULL,
 `data_smtext` varchar(1000) COLLATE utf8_unicode_ci DEFAULT NULL,
 `data_lgtext` longtext COLLATE utf8_unicode_ci,
 `data_numeric` decimal(20,2) DEFAULT NULL,
 `linkid` int(11) DEFAULT NULL COMMENT 'ID value of specific item',
 `cfid` int(11) NOT NULL COMMENT 'Custom field ID',
 PRIMARY KEY (`cfdid`),
 KEY `data_smtext` (`data_smtext`(333)),
 KEY `linkid` (`linkid`),
 KEY `cfid` (`cfid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

卡住的查询如下:

SELECT NOTEDATE, REF1, REF2, LASTDATE, USERID, feed_hcp_leasenote.NOTETEXT, leases.lid, lease_notes.lnid
FROM feed_hcp_leasenote
JOIN customfield_data mrileaseid ON feed_hcp_leasenote.LEASID = mrileaseid.data_smtext AND mrileaseid.cfid = ?
JOIN leases ON mrileaseid.linkid = leases.lid
JOIN suites ON leases.sid = suites.sid
JOIN floors ON suites.fid = floors.fid
JOIN customfield_data coid ON floors.bid = coid.linkid AND coid.cfid = ? AND coid.data_smtext = feed_hcp_leasenote.BLDGID
JOIN customfield_data status ON leases.lid = status.linkid AND status.cfid = ? AND status.data_smtext <> ?
LEFT JOIN lease_notes ON leases.lid = lease_notes.lid
LEFT JOIN customfield_data notedate ON lease_notes.lnid = notedate.linkid AND notedate.data_date = feed_hcp_leasenote.NOTEDATE AND notedate.cfid = ?
LEFT JOIN customfield_data ref1 ON lease_notes.lnid = ref1.linkid AND ref1.data_smtext = feed_hcp_leasenote.REF1 AND ref1.cfid = ?

我的目标是返回feed_hcp_leasenote中的所有记录,并根据lease_notes.lnid是否为null,根据需要插入或更新记录(空值将是插入,而不是空值将是更新。)问题是提供的数据使用4个字段的组合来确定唯一性:BLDGID,LEASID,NOTEDATE和REF1。如果没有正确的BLDGID和LEASID(在我的查询中翻译为有效的 lid ,则不会存在注释。它可以匹配具有有效盖子,NOTEDATE和REF1的现有记录,但如果没有那么我可以认为这是一个新记录。

如果我从SELECT中删除所有LEFT JOIN和lease_notes.lnid,它会正确执行并给我所有记录。由于我无法将原始查询用于工作,因此我想要循环所有结果并执行另一个 SELECT以查看注释和ref1是否匹配。如果没有,我插入,否则更新。虽然这种方法有效但它每秒只能处理大约20条记录,但当我在破解时处理30,000条记录时这是一个问题。

自从我在之前的一个问题中被问到这个问题以来,这是我的查询的解释:

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra
1   SIMPLE  status  ref     data_smtext,linkid,cfid     cfid    4   const   934     Using where
1   SIMPLE  mrileaseid  ref     data_smtext,linkid,cfid     linkid  5   rl_hpsi.status.linkid   19  Using where
1   SIMPLE  leases  eq_ref  PRIMARY,sid     PRIMARY     4   rl_hpsi.mrileaseid.linkid   1   Using where
1   SIMPLE  suites  eq_ref  PRIMARY,fid     PRIMARY     4   rl_hpsi.leases.sid  1    
1   SIMPLE  floors  eq_ref  PRIMARY,bid     PRIMARY     4   rl_hpsi.suites.fid  1    
1   SIMPLE  feed_hcp_leasenote  ref     BLDGID,LEASID   LEASID  153     rl_hpsi.mrileaseid.data_smtext  19  Using where
1   SIMPLE  coid    ref     data_smtext,linkid,cfid     data_smtext     1002    rl_hpsi.feed_hcp_leasenote.BLDGID   10  Using where
1   SIMPLE  lease_notes     ALL     NULL    NULL    NULL    NULL    15000    
1   SIMPLE  notedate    ref     linkid,cfid     linkid  5   rl_hpsi.lease_notes.lnid    24   
1   SIMPLE  ref1    ref     data_smtext,linkid,cfid     data_smtext     1002    rl_hpsi.feed_hcp_leasenote.REF1     10   

有人能指出我正确的方向吗?谢谢!

1 个答案:

答案 0 :(得分:1)

从我们的评论:

答案是添加使目标表具有唯一条目的列,并在其上创建复合唯一键。然后,当插入该表时,使用INSERT ON DUPLICATE KEY UPDATE来防止重复数据。插入完成后,如果不再需要这些列,则可以删除这些列,以防止将数据存储在多个表中。