2017-03-14 6 views
0

シナリオを問い合わせ:

は、2つのテーブルがあるとします。表Aと表B Aが100万行が含まれ、表Bには表A速度差が

におけるいくつかの場合ではないすべての行を含めることができます
# Table A 
,----,-------,------,---------,-------,---------, 
| id | email | name | surname | score | updated | 
'----'-------'------'---------'-------'---------' 
# INDEXES 
PRIMARY email 
INDEX date_open 
INDEX date_click 
INDEX date_send 
INDEX score 

# Table B 
,-------,-------,---------, 
| email | score | updated | 
'-------'-------'---------' 
# INDEXES 
PRIMARY email 
INDEX score 

質問:

を使用すると、1つのあなたが選ぶだろう2つのクエリの1、のどちらかを選択する必要があると仮定?

REPLACE INTO `Table_B` (`email`, `score`, `updated`) SELECT `email`, `score`, `updated` FROM `Table_A`; 
REPLACE INTO `Table_B` (`email`, `score`, `updated`) SELECT `email`, `score`, `updated` FROM `Table_A` WHERE `updated` = 'yes'; 

どのクエリが高速になりますか?表Aのupdatedにインデックスを追加すると、クエリが高速化されますか?

答えて

1

私はではありません。は、1回のクエリで数百万行を実行します。何かが間違っている - タイムアウト、バッファ制限など。そうすると失敗するでしょう。MyISAMの場合、タスクは部分的に行われ、中断した箇所を知る方法はありません。 InnoDBの場合、部分的に何をしたのか、多くの時間を費やすでしょう。

私は、狭いB短くする...

  1. コピー広い、背の高い、テーブルAからわずかscores質問...それは約怪しげなのですか?それはマルチテーブルUPDATEです。または、BSELECT .. FROM Aとして再作成してください。
  2. Bには「新しい」得点が含まれており、Aにコピーする必要がありますか?これもマルチテーブルUPDATEです。
  3. 'source'テーブルに新しい行がある可能性があります。それはIODKUが必要です。しかし、他の列はどうですか?
  4. このような大量のコピーは、「間違った」スキーマ設計を示すことがあります。つまり、データフローで定期的に実行する場合は、スコアを別のテーブルに保存し、必要に応じてJOINをそのまま使用します。 ではなく、は、スコアを持つ別のテーブルで十分な場合は、テーブルを更新するタスクを実行します。しかし、...「すべてではない」スコアが来るので、これはうまくいかないでしょうか?

「1回のパスで行うには大きすぎます。 PRIMARY KEY(email)を使用すると、1つのテーブルを歩きやすくなり、UPDATEまたはIODKUのテーブルを他のテーブル(例:1000 emails)で実行することができます。このようなチャンクの方法についての説明は次のとおりです。 次のチャンクの終わりを見つける方法としてSELECT email FROM tbl WHERE email > $left_off ORDER BY email LIMIT 1000,1に注意してください。