2016-05-31 7 views
0

私はメインテーブルメインテーブルを持っています。約4.5M行あります。 これは、クエリを作成します次のとおりです。MySQL - 参加による更新が突然に終わる

create table MainTable(
    status_day date DEFAULT NULL, 
    i_station_id int DEFAULT NULL, 
    i_TZ int DEFAULT NULL, 
    CID int DEFAULT NULL, 
    Calc1 double DEFAULT NULL, 
    Calc2 double DEFAULT NULL, 
    ... 
    Calc80 double DEFAULT NULL, 
UNIQUE KEY uniqueindex (status_day, i_station_id, i_TZ, CID) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 

私は別のTEMPテーブルの値で、いくつかのfeildsを更新する必要があります。それはおよそ760Kの行を持っており、それが文を作成します:

create temporary table TEMP (
    status_day date DEFAULT NULL, 
    i_station_id int DEFAULT NULL, 
    i_TZ int DEFAULT NULL, 
    CID int DEFAULT NULL,, 
    Calc13 double DEFAULT NULL, 
    Calc14 double DEFAULT NULL, 
    Calc17 double DEFAULT NULL, 
    Calc24 double DEFAULT NULL, 
    Calc68 double DEFAULT NULL, 
    Calc70 double DEFAULT NULL, 
UNIQUE KEY indexxx (status_day, i_station_id, i_TZ, CID) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 

何らかの理由で、この更新クエリ:

は〜3時間かかります。それは理にかなっていますか?私にはあまりにも長いようだ。

update MainTable as A join TEMP as B on 
     (A.status_day = B.status_day and 
     A.i_station_id = B.i_station_id and 
     A.i_TZ = B.i_TZ and 
     A.CID = B.CID) 
set 
    A.Calc13 = B.Calc13, 
    A.Calc14 = B.Calc14, 
    A.Calc17 = B.Calc17, 
    A.Calc24 = B.Calc24, 
    A.Calc68 = B.Calc68, 
    A.Calc70 = B.Calc70 

これは

Explain select 
    * 
from MainTable as a join TEMP as b on 
    (a.status_day = b.status_day and 
    a.i_station_id = b.i_station_id and 
    a.i_TZ = b.i_TZ and 
    a.CID = b.CID) 




ID  select_type table type possible_keys key   key_len rows 
1  SIMPLE  b  ALL  indexxx        692967 
1  SIMPLE  a  ref  uniqueindex uniqueindex 23  1 

任意のアイデアの結果ですか?

ありがとうございます。 :)

更新:回答:サーバーへのメモリとCPUの増加は、これを直ちに解決しました。

+0

説明プランの行数を増やしてください。 また、空のフィールドのように、参加するフィールド間に重複する値がありますか?これにより、更新プログラムで一致する行が非常に多く見つかる可能性があり、実行時間が長くなることが説明されます。 – iLikeMySql

+0

ちょっと:)結合されたフィールドに重複はありません。両方のテーブルの一意のキーです... 説明出力に行数を追加しました –

+0

私はかつて同じような問題があり、それはディスクI/Oでした。 rhavendcが書いたように3時間はあまりにも多くのクエリのためです。しかし、あなたのクエリはきれいに見え、行の数は実際にはそれほど高くありません。同じ時間に別の大きなトランザクションが実行されていた可能性はありますか?可能であれば、別のサーバーでクエリをテストし、そうでない場合は、テーブルのコピーを作成し、インデックスを再構築し、テーブルとは何の関係もないことを確認するためにコピーを使用してクエリをテストします。 – iLikeMySql

答えて

0

質問が3時間かかる理由はあまりよく分かりませんが、それは不合理です。たぶん、あなたが参加している列に何か問題がありますが、あなたは、クエリのようにも行うことができます:3時間コストの

UPDATE MainTable A, TEMP B 
SET 
    Calc13 = B.Calc13, 
    Calc14 = B.Calc14, 
    Calc17 = B.Calc17, 
    Calc24 = B.Calc24, 
    Calc68 = B.Calc68, 
    Calc70 = B.Calc70 
WHERE 
    A.status_day = B.status_day 
    AND A.i_station_id = B.i_station_id 
    AND A.i_TZ = B.i_TZ 
    AND A.CID = B.CID 
0

パートは巨大な「ロールバック」のログを構築しています。

私は、繰り返しごとに1000行(またはそれ以下)を更新するように見ていきます。または、より簡単には、UPDATEの中にある1つの行をすべてTEMP.status_dayに更新し、次にTEMP.status_dayに移動します。ストアドプロシージャまたはアプリケーションコードのいずれかを使用できます。

の場合は、それぞれUPDATEの後に必ず入力してください。 (または単にautocommit=1を使用してください)

More on chunking

関連する問題