0

あるソースから別のソースへのデータインポートルーチンに取り組んでいますが、独自の一意の識別子を持たないテーブルが1つあります。代わりに、4つのフィールドの組み合わせを使用して、変更するレコードを決定します。私のソーステーブルの構造は以下のとおりです。

feed_hcp_leasenoteテーブル:

BLDGID varchar(255),
LEASID varchar(255),
NOTEDATE varchar(255),
REF1 varchar(255),
NOTETEXT varchar(8000),
tempid int PRIMARY, AUTONUMBER

最初の4つは、全体として評価されたときに、ソースデータベースでレコードを一意にするフィールドです。このデータを2つのテーブルにインポートしています。1つはメモ用で、もう1つは他のフィールド用です。新しいデータベースの構造は次のとおりです。

リースノートテーブル:

lnid int PRIMARY AUTONUMBER,
notetext longtext,
lid int (lease ID, links to lease table)

customfield_dataテーブル(他のデータを保持します):

cfdid int PRIMARY AUTONUMBER,
data_date dateteime,
data_smtext varchar(1000),
linkid int (links the data to its source ID)
cfid int (links the data to its field type)

私が遭遇している問題は、新しいデータベースに一致するものがない状態でソースデータベースに存在するレコードを識別しようとすると、クエリがレコードを複製して、クエリが終了せず、サーバーがロックされるようになることです。BLDGIDとLEASIDに基づいて正常にクエリを実行し、クエリを適切なレコードに制限できますが、NOTEDATEフィールドとREF1フィールドにエイリアスされたcustomfield_dataテーブルを結合しようとすると、レコードが指数関数的に複製され始めます。これが私の質問です:

SELECT NOTEDATE, REF1, REF2, LASTDATE, USERID, NOTETEXT, lid
FROM feed_hcp_leasenote
JOIN customfield_data mrileaseid ON feed_hcp_leasenote.LEASID = mrileaseid.data_smtext AND mrileaseid.cfid = 36
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 = 1 AND coid.data_smtext = feed_hcp_leasenote.BLDGID
JOIN customfield_data status ON leases.lid = status.linkid AND status.cfid = 27 AND status.data_smtext <> 'I'
WHERE tempid NOT IN (
  SELECT tempid
  FROM feed_hcp_leasenote
  JOIN customfield_data mrileaseid ON feed_hcp_leasenote.LEASID = mrileaseid.data_smtext AND mrileaseid.cfid = 36
  JOIN leases ON mrileaseid.linkid = temp_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.data_smtext = feed_hcp_leasenote.BLDGID AND coid.cfid = 1
  JOIN customfield_data notedate ON STR_TO_DATE(feed_hcp_leasenote.NOTEDATE, '%e-%b-%Y') = notedate.data_date AND notedate.cfid = 55 
  JOIN customfield_data ref1 ON feed_hcp_leasenote.REF1 = ref1.data_smtext AND ref1.cfid = 56
  JOIN lease_notes ON leases.lid = lease_notes.lid AND notedate.linkid = lease_notes.lnid AND ref1.linkid = lease_notes.lnid )

現時点では、問題をNOT INサブクエリに絞り込んでいます。その部分だけを実行すると、サーバーがクラッシュします。問題は、同じBLDGID、LEASID、NOTEDATE、およびREF1(4つすべてではない)を持つ複数のノートが存在する可能性があるため、クエリがそれ自体を選択し続け、効果的に無限ループを作成することだと思います。

一意のIDを含めるようにソースデータベースを変更する以外に(これはできません)、誰かがこれに対する解決策を見ていますか?前もって感謝します!

(フィードバックに基づいて編集)

情報不足でごめんなさい、心配でした。基本的に、feed_hcp_leasenoteのデータを、制御できない別のデータベースからダンプされたCSVファイルからインポートしています。データがサーバーにインポートされたら、SELECT WHERE tempid NOT INクエリで使用することを考えて、tempidフィールドを追加しますが、そのアプローチとは関係ありません。

私の目標は、feed_hcp_leasenoteのデータを2つのテーブルに分割することです。1次レコード(一意のIDを持つ)とメモ自体を保持するlease_noteと; レコードに関連する他のデータを保持するcustomfield_data。

ソースデータフィードは約65,000レコードで構成されており、残りは非アクティブ化されたレコードに接続されているため、そのうち約25,000レコードをインポートしています。

(2回目の編集)

関連するテーブルのビジュアルスキーマ:http ://www.tentenstudios.com/clients/relynx/schema.png

EXPLAINクエリ:

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra
1   PRIMARY     status  ref     data_smtext,linkid,cfid     cfid    4   const   928     Using where
1   PRIMARY     mrileaseid  ref     data_smtext,linkid,cfid     linkid  5   rl_hpsi.status.linkid   19  Using where
1   PRIMARY     leases  eq_ref  PRIMARY,sid     PRIMARY     4   rl_hpsi.mrileaseid.linkid   1   Using where
1   PRIMARY     suites  eq_ref  PRIMARY,fid     PRIMARY     4   rl_hpsi.leases.sid  1    
1   PRIMARY     floors  eq_ref  PRIMARY,bid     PRIMARY     4   rl_hpsi.suites.fid  1    
1   PRIMARY     feed_hcp_leasenote  ref     BLDGID,LEASID   LEASID  768     rl_hpsi.mrileaseid.data_smtext  19  Using where
1   PRIMARY     coid    ref     data_smtext,linkid,cfid     data_smtext     1002    rl_hpsi.feed_hcp_leasenote.BLDGID   10  Using where
2   DEPENDENT SUBQUERY  feed_hcp_leasenote  eq_ref  PRIMARY,BLDGID,LEASID   PRIMARY     4   func    1    
2   DEPENDENT SUBQUERY  mrileaseid  ref     data_smtext,linkid,cfid     data_smtext     1002    rl_hpsi.feed_hcp_leasenote.LEASID   10  Using where
2   DEPENDENT SUBQUERY  leases  eq_ref  PRIMARY,sid     PRIMARY     4   rl_hpsi.mrileaseid.linkid   1    
2   DEPENDENT SUBQUERY  suites  eq_ref  PRIMARY,fid     PRIMARY     4   rl_hpsi.leases.sid  1    
2   DEPENDENT SUBQUERY  floors  eq_ref  PRIMARY,bid     PRIMARY     4   rl_hpsi.suites.fid  1    
2   DEPENDENT SUBQUERY  ref1    ref     data_smtext,linkid,cfid     data_smtext     1002    rl_hpsi.feed_hcp_leasenote.REF1     10  Using where
2   DEPENDENT SUBQUERY  lease_notes     eq_ref  PRIMARY     PRIMARY     4   rl_hpsi.ref1.linkid     1   Using where
2   DEPENDENT SUBQUERY  coid    ref     data_smtext,linkid,cfid     data_smtext     1002    rl_hpsi.feed_hcp_leasenote.BLDGID   10  Using where
2   DEPENDENT SUBQUERY  notedate    ref     linkid,cfid     linkid  5   rl_hpsi.ref1.linkid     19  Using where
4

1 に答える 1

0

独自の一意の識別子はありません。代わりに、4 つのフィールドの組み合わせを使用して、変更するレコードを決定します。

いいえ: 4 つのフィールドの組み合わせが一意のキーを構成する場合、一意の識別子が得られます。

BLDGID varchar(255)、LEASID varchar(255)、NOTEDATE varchar(255)、REF1 varchar(255)、NOTETEXT varchar(8000)

したがって、データが実際にどのように構造化されているかを知らないか、どちらも知らない MSAccess プログラマからこれを取得します。

SELECT NOTEDATE、REF1、REF2、LASTDATE、USERID、NOTETEXT、ふた FROM feed_hcp_leasenote

ああ、神様。それが答えなら、あなたは間違った質問をしています。

一意の ID を含めるようにソース データベースを変更する以外に (これはできません)、これに対する解決策はありますか?

別の仕事を探す?真剣に。主キーをインポート テーブルに追加できない場合、または主キーが定義された一時テーブルにインポートできない場合は、これを修正するために膨大な時間を費やすことになります。

ところで: innodb は最大 3072 バイト (32 ビットでは 1024) のキーを処理しますが、列のサイズを減らすか、実際の PK データのハッシュを主キーとして使用するまで、これは犬のように実行され続けます。

あなたの質問から、追加する行数/データベースに既に存在する行数が明確ではありません。また、他のテーブルの構造も提供していません。 また、パフォーマンスの問題の出発点となる説明計画も提供していません。

これをもっと速く実行できる可能性があります - あなたが提供した情報からは言えません. しかし、スキーマを変更せずに高速化する必要があるというばかげた制約を考えると、他にどんな恐怖が待っているのだろうと思います。

現在のスキーマの詳細を知らなくても、現在のクエリをいくつかのコンポーネントに分割し、それぞれをチェックして、インポート テーブルにスコアを保持し、そのスコアを使用して一致しないデータがあったものを特定することができると思いました。ただし、これにはスキーマの変更も必要です。

ところで、SQL の DISTINCT キーワードの Google があります。

于 2013-03-04T21:45:08.080 に答える