2011-12-14 12 views
0

私は、数千ものアイテム(通常は約5000個のアイテム)を保持できる配列を持っています。 この配列を数百に分割して処理し、残りの項目を続行する必要があります。 これまでのところ、私は遅い全体の配列を扱います。 私のコードは数百のPHP分割配列

foreach($result as $p){ 
       $sqlQuery = mysql_query("INSERT INTO message_details(contact, message_id)VALUES('$p', $message_last_id)"); 
       $last_id = mysql_insert_id(); 
       $xmlString .= "<gsm messageId=\"$last_id\">".$p."</gsm>"; 
       $cnt++; 
      } 

がどのように私は、数百の配列内のアイテムを処理することができますか?例えば。あなたはコードでそれを行うにはを持っている場合は100、そして200、そして300のなど

よろしく、 ニコス

+0

なぜsleep()を使わず、SQLサーバを復旧させてみましょうか?また、各反復でXMLファイルを更新します。 –

+0

何百ものアイテムの処理チャンクがそれより優れているのはなぜですか? – Jon

+0

ボトルネックは、実際にはインサート自体であるかもしれません。 'INSERT INTO ... VALUES(row1)、(row2)、... '構文を使って、複数の行を一度に挿入することから始めます。テーブルをロックすると、IDを手動で派生させることができます。 –

答えて

1

あなたは100個の要素それぞれの配列にチャンクにあなたの配列をPHPの関数array_chunkを使用することができます。ここでは、array_chunkのドキュメントはlinkです。しかし、指摘したように、これはボトルの首になる可能性は低いです。

+0

これは私が必要としていたものです。 $ chunk_result = array_chunk($ result、150、true); foreachの($ $チャンクとしてchunk_result) {ここで //コードここで foreachの($ pと$チャンク) { //コード } } – Nicos

2
foreach($result as $p){ 
    $sqlQuery = mysql_query("INSERT INTO message_details(contact, message_id)VALUES('$p', $message_last_id)"); 
    $last_id = mysql_insert_id(); 
    $xmlString .= "<gsm messageId=\"$last_id\">".$p."</gsm>"; 
    $cnt++; 

    if ($cnt % 1000 == 0) { usleep(100) } 
} 

あなたが欲しいものに応じusleepまたはsleepを使用することができます。私はすでにこれを使いました。あなたはパフォーマンスを得る。それを試してみてください。 message_detailsの最後のIDを選択する

まず:

+0

これはオーバーフローすることとにデータを交換するためにデータベース・バッファを防止していhdd?私には分かりません。 –

+0

@MikulasDiteデータベースに挿入するデータが大量にある場合、またはSGDBをバッファするか、アプリケーションメモリをオーバーフローさせた場合。一つの方法はある意味で影響を受けます。私が投稿したこのメソッドは、この実行をSGDBではなく、アプリケーションマシン上で保持します。 –

+0

ガベージコレクタは確かに反復配列の行を削除しないので、実際にはPHPのメモリオーバーフローを防ぎません。私はそれがある意味でパフォーマンスを改善すべきだと私は同意しますが。どんな程度まで進んでいるかもわかりません。 –

3

たぶん、あなたはそのようにそれを試してみてください。その後、

$sqlQuery = mysql_query("SELECT %last_id_col_name% FROM message_details ORDER BY %last_id_col_name% DESC LIMIT 1".$sInserts); 

$sInserts = ''; 

foreach($result as $p){ 
    $sInserts .= "('{$p}', {$message_last_id}),"; 
} 

//Remove last "," from Insert-String 
$sInserts = substr($sInserts,0,-1); 

//Insert all with one query 
$sqlQuery = mysql_query("INSERT INTO message_details(contact, message_id)VALUES".$sInserts); 

は、あなたが を最初に選択したidが1より大きくなるテーブルからすべてのエントリを選択して、あなたがいる場合

$xmlString .= '<gsm messageId="'.$last_id.'">'.$p.'</gsm>'; 

に書き込みますこのようにすると、千の代わりに3つのDBクエリしか必要ありません。

+0

自動インクリメントはIDを処理するため、挿入クエリに独自のIDを入力する必要はありません。また、文字列の連結はひどく見えます。私はpdoまたは何かより高いレベルに配列を渡すことに行きます。 –

+0

私は彼のインサートだけを修正しました。 '$ message_last_id'がそのテーブルのidを意味するのかどうかわかりません。私が示したかったのは、各ループごとに挿入する必要はないということです。これが、なぜスクリプトがそれを長く取るのかという理由です。 – mat