2016-07-07 4 views
0

私は2つのテーブルcustomercustomer_risk_scoreを持っています。顧客テーブルは、新規顧客が記録されると大きくなります。顧客データをcustomer_risk_scoreに挿入します。Maria DBが大量のデータを含む大きなクエリを実行できない

私のシナリオでは、customer_risk_scoreテーブルに245,890を超えるエントリがあり、顧客エントリは699,780レコードに増加しました。

私はphpMyAdminを介して、

INSERT INTO customer_risk_score (rim, client_code, calculated_on) 
    SELECT rim, client_type, Now() 
    FROM customer 
    WHERE rim NOT IN (SELECT rim FROM customer_risk_score) 

にこのクエリを実行するとcustomer_risk_scoreは699780が約245890レコードと顧客テーブルを有している場合には、その時点で、クエリは永遠ませ終了またはエラーメッセージが実行されません。それをテストして3時間待ってから手動で終了させました。私は、show processlistを実行することによって、ターミナル経由でDBMS上で実行されているすべてのプロセスを強制終了することに到達しました。これは実行中の唯一のプロセスでした。

customer_risk_scoreが切り捨てられてクエリを再実行すると、customerテーブルの特定のエントリをcustomer_risk_scoreに挿入するのに約3秒かかります。

このクエリは2時間ごとに実行されるようにスケジュールされており、その遅延の原因は私の質問です。 mariaDBバージョンのバグですか、あるいは私のクエリが間違った方法で設計されていますか?使用していますMariaDB VERSION @@ version 5.5.49-MariaDB-1ubuntu0.14.04.1

ありがとうございます!

+0

私の質問を編集するための@Jarlhに感謝します。それは私にクールな答えを持っていた –

答えて

1

私が参加left join ... is nullnot inサブクエリを変更するだろうとリムの列が両方のテーブルにインデックス付けされていることを確認します:

INSERT INTO customer_risk_score (rim, client_code, calculated_on) 
    SELECT c.rim, c.client_type, Now() 
    FROM customer c 
    LEFT JOIN customer_risk_score crs on c.rim=crs.rim and crs.rim is null 

、より多くのレコードが挿入されているとして、あなたの元の表のサブクエリが急速に成長しますcustomer_risk_scoreテーブルに追加します。私の提案されたソリューションの結合条件は、これらのレコードのほとんどを削除します。

もう1つの解決策は、not inではなくサブクエリでnot exists演算子を使用することです。

+0

私は列をインデックス化せずにあなたのクエリを試みたと私は手動でそれを7分で終了したが、私は14.73秒かかりました。 Thanks Shadow –

+0

リムの列にインデックスを付けることなく、MySQLはレコードを照合するためにテーブル全体をスキャンする必要があります。 – Shadow

0

@シャドウの解決策は近いですが、致命的な欠陥がありました。これは、より良い動作するはず:

INSERT INTO customer_risk_score (rim, client_code, calculated_on) 
    SELECT c.rim, c.client_type, Now() 
    FROM customer c 
    LEFT JOIN customer_risk_score crs on c.rim=crs.rim 
    WHERE crs.rim is null; -- see note below 

NULLのチェックがON中であってはなりません。それはWHEREにある必要があります。

そして、はい、rimのインデックスを作成する必要があります。

関連する問題