2017-05-19 8 views
0

UIDのリストを持つ配列(PHPで)があり、そのUIDを持つ行をすでに含んでいるMySQLテーブルをUIDのあるインデックスで更新したい配列。配列内の位置に基づいて複数のMySQL行を更新する

だから、のUIDの私の配列は次のようになります。私は、その後の効果にテーブルを更新したい

[1123,4542,3456,2212,2346,7778,577885,44322] 

POS | UID 
---------- 
1 |1123  
2 |4542  
3 |3456  
etc  
---------- 

データセット(配列)は、(非常に大きくなる可能性がある1000 +私が更新しているテーブルには、他のデータセットの一部である他のUIDも含まれています(ただし、一意のUIDを持ちます)。

私は明らかにループと更新ステートメントの読み込みでこれを行うことができますが、単一またはほんの数のステートメントでそれを行うより効率的な方法があるのだろうかと思っています。

私は多くの検索を行い、設定/固定数の値や他のデータベーステーブルに基づいて更新するだけの回答を見つけることができますが、配列の長さは更新されるデータセットによって異なります。

+0

ためのアプローチ

みんなありがとうとはかなり満足しているこの方法を行うことによって、明らかなパフォーマンスの不利益があるように表示されません。 **一つの**準備された更新ステートメントを使用し、それを複数回ループで実行します。それが遅すぎる場合は、配列を一括挿入した一時テーブルに格納することができます。 –

+0

ありがとうPaulは、私が作る必要がある可能性がある更新の可能性が高いため、可能な限りループを避けることを望んでいましたが、それを行うより効率的な方法がない場合は、フォールバックの位置として使用します – jTrouble

+0

簡単で簡単な解決策がどのように実行されるか最初にテストします。あなたは積極的に驚くかもしれません。 –

答えて

0

プリペアドステートメントでの更新が十分に速いものではない場合は、一括挿入されたテンポラリテーブルにデータをプリロードすることができます。ここではPDOのためのサンプルコードは次のとおりです。

// $uids = [1123,4542,3456,2212,2346,7778,577885,44322,...] 
$values = []; 
foreach ($uids as $key => $uid) { 
    $pos = $key+1; 
    $values[] = "($uid,$pos)"; 
} 
$values = implode(',', $values); 
$pdo->exec(" 
    drop temporary table if exists tmpdata; 
    create temporary table tmpdata (uid int, pos smallint) engine=memory; 
    insert into tmpdata(uid, pos) values $values; 
    update test d 
    join tmpdata t using(uid) 
    set d.pos = t.pos; 
"); 

私は10KのUIDの配列でこれをテストしてみた - そしてそれは私のマシン上では50msで実行されます。

注:SQLインジェクションを防止するために、データの検証とサニタイズが必要な場合があります。

レプリケーションを使用する場合は、thisも参照してください。

0

謝罪すべて、質問を更新することを忘れてしまった - オブジェクトをループし、それぞれを新しいクエリで更新する単純なオプションを使用しました。

私は特定のタイミングを持っていないが、ちょうどので、私は助け

関連する問題