2016-10-08 10 views
0

私はあるテーブルから別のテーブルにIDを更新する簡単な作業があります。 私の現在のソリューションは非常に遅く、phpとmysqlの両方で動作しています。 セクターテーブルには約9000個のレコードがあり、ソーステーブルには17Milがあります。 $ sector->コードは、これまでのところ、私はこれを得たforeachよりも速いクエリ

varchar型にある:

foreach(Sector::orderBy('id','DESC')->get() as $sector){ 
     DB::select(DB::raw("UPDATE `sources` SET `sector_id` = $sector->id WHERE `sector` = '$sector->code'")); 
    } 

これは、各部門の分については取っているし、それらを実行している場合は、すべてが一週間か何かで完了します。..どのオプションではありません。

答えて

0

まず、データベースにはインデックスが付いている必要があります。 17Milのエントリには、sectorのインデックスが必要です。これは各セクターを意味し、セクターに一致するレコードのサブセットのみがチェックされます。

第2に、これは単一のクエリで達成可能でなければなりません。

UPDATE `sources`,`sector` SET `sources`.`sector_id` = `sector`.`id` 
     WHERE `sources`.`sector` = `sector`.`code`; 

これは、テーブルの複数の移行を停止し、更新を高速化する必要もあります。

参考: - MySql : Update syntax - mySqlでマルチテーブルクエリを実行する方法。

+0

問題は、すでにこのテーブルにインデックスとして3つのフィールドがあることです。そのクエリを実行しようとしましたが、それは私にとっては遅いようでした。 –

0

Iは、好ましくは(..あなたの問題のため

ソリューション1

最も最適かつ最高のフィットソリューションは、cronジョブを作成することで、問題のための2つの解決策があると思うし、定期的に実行します夜に)。あなたの頭痛を解決します。

ここには、cronジョブを管理するためのリンクhttps://code.tutsplus.com/tutorials/managing-cron-jobs-with-php--net-19428があります。

ソリューション2

ソリューション2符号化規格では、クエリのループ内部を書くことがないと述べているルールがある、あなたの現在のコードを最適化です。

ステップ1:UPDATEing 17M行が遅い多くの理由がありますが、この

UPDATE sources 
SET sector_id= (CASE id WHEN 1 THEN 'XXX' 
       WHEN 2 THEN 'XXXX' 
       WHEN 3 THEN 'XXXX' 
     END) 
WHERE id IN(1,2 ,3); 
+0

Cronjobは解決策ですが、私の場合ではありません.2番目の例ではOKですが、9kのレコードがあります。 –

+0

@CodewallKidsで更新クエリパターンを使用すると、ループ内でクエリ文字列を動的に作成し、 ..私はそこに他の解決策があるのか​​分からない。あなたが何らかの種類のPHPフレームワークを使用している場合、フレームワークはこの頭痛から多くを助けます。 – anuraj

0

のような単一のクエリを使用してDBを更新してください。その1つは、クラッシュが発生した場合、InnoDBが情報をROLLBACKに構築することです。これは、そのような大きなテーブルでは特にコストがかかります。

PRIMARY KEYに基づいてスキャンして、一度に1Kまたは10K行にテーブルを「チャンク」することを検討します。 Hereはそれ以上の議論です。

このような大規模なアップデートでは、テーブルが他の用途からいくらかブロックされることに注意してください。アップデート中に他のすべてのアクティビティを停止しますか(実装されていますか?)そうでない場合は、部分的に更新されたテーブルの影響や、別の方法でセクタを見るために必要なコードの変更(IDとコード)を教えてください。

関連する問題