0

私は一連の 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 の 2 つのテーブルにインポートしようとしています。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 であるかどうかに応じて、必要に応じてレコードを挿入または更新することです (null は挿入され、null は更新されません)。 data は、BLDGID、LEASID、NOTEDATE、および REF1 の 4 つのフィールドの組み合わせを使用して一意性を判断します。適切な BLDGID と LEASID がなければメモは存在しません (クエリで有効な lidに変換されます。有効なふた、NOTEDATE、および REF1 を持つ既存のレコードと一致する可能性がありますが、それらが一致しない場合は、新記録。

SELECT からすべての LEFT JOIN と lease_notes.lnid を切り取ると、正しく実行され、すべてのレコードが得られます。元のクエリを機能させることができなかったので、すべての結果を循環させ、別のSELECT を実行して、notedate と ref1 が一致するかどうかを確認するというアイデアを試しました。そうでない場合は挿入し、そうでない場合は更新します。このアプローチは機能しますが、1 秒あたり約 20 レコードしか処理できません。

以前の質問でそれについて尋ねられたので、これが私のクエリの EXPLAIN です。

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   

誰かが私を正しい方向に向けることができますか? ありがとう!

4

1 に答える 1

1

私たちのコメントから:

答えは、エントリを宛先テーブルに一意にする列を追加し、それらに複合一意キーを作成することです。次に、そのテーブルに挿入するときに、INSERT ON DUPLICATE KEY UPDATEデータの重複を防ぐために使用します。挿入が完了したら、不要になった列を削除して、複数のテーブルにデータを格納しないようにすることができます。

于 2013-03-08T16:38:50.577 に答える