2016-11-13 7 views
1

複数のページに分割されたJSONファイルを解析するPHPスクリプトのセットアップがあります。MySQLのマルチクエリー非常に遅く、単純なトランケートクエリの代わりに?

このPHPスクリプトはJSONを解析し、それをMySQLデータベースに挿入します。

単一のクエリで

...(TRUNCATE声明なし):multi_queryのオンscript execution time: 16.451724052429

で成功し

if ($count > 0) { 

//check toperform operation 

foreach ($jsondecode as $entries) { 

//getting variables here 

$sql = "INSERT INTO table (title, handle, imagesrc) 
VALUES ('".$title."', '".$handle."', '".$imagesrc."')"; 

if ($connect->query($sql) === TRUE) { 
echo "New record created successfully"; 
} else { 
echo "Error: " . $sql . "<br>" . $connect->error; 
} 
} 
} 

結果....:

if ($count > 0) { 
    $sql = "TRUNCATE table;"; 

foreach ($jsondecode as $entries) { 

//getting variables here 

$sql.= "INSERT INTO table (title, handle, imagesrc) 
VALUES ('".$title."', '".$handle."', '".$imagesrc."')"; 

if (!$mysqli->multi_query($sql)) { 
echo "Multi query failed: (" . $mysqli->errno . ") " . $mysqli->error; 
} 

do { 
if ($res = $mysqli->store_result()) { 
    var_dump($res->fetch_all(MYSQLI_ASSOC)); 
    $res->free(); 
} 
} while ($mysqli->more_results() && $mysqli->next_result()); 


} 
} 

結果script execution time: 278.05182099342、ほぼ5分で正常に終了しました。

TRUNCATEの前に、INSERTの表があります。

私はこのスクリプトを12時間ごとに実行する予定のWebサーバーCRONジョブでこれを実行します。

明らかに、1つのクエリと複数のクエリの間にこのような膨大な実行時間の差があります。何かできることは何ですか?

私の唯一の考えは、TRUNCATEステートメントを12時間ごとに実行するだけの、別のCRONジョブスクリプトを設定することです。このメインスクリプトが実行される1分前です。これはうまくいくはずですが、当然理想的ではないので、私は単なるスクリプトではなく複数のスクリプトを扱わなければなりません。

+1

あなたの問題に対する答えはありませんが、挿入値もカンマで区切って複数の項目を1つのクエリとして実行できます。 – Scuzzy

+1

クエリが作成された後、すべての繰り返しではなく、 'insert'を実行します。たとえば、次のようになります。 – chris85

答えて

1

このような大きな違いがある理由は、余分なキャラクターが1つ存在する理由です!

$sql.= "INSERT INTO table (title, handle, imagesrc) 
VALUES ('".$title."', '".$handle."', '".$imagesrc."')"; 

既存のクエリに新しいクエリを追加し続けますが、ループ内でそのバルーンクエリを実行し続けます。コードを正しくインデントしていないため、明らかではない可能性があります。だから、ここで重大な間違いは黙っている!

JSONの入力行ごとにテーブルを切り捨て、すべてをもう一度挿入します。

さらに、これは実際には複数のクエリを使用するべきではありません。ループ外でtruncateクエリを実行します。次に、ループ内で挿入クエリを実行します。

他の人が、複数のVALUESセットを使用して1つの挿入クエリを作成することが少し速いかもしれないと指摘しているので。あるいは、トランザクション自動コミットをオフにして、最後にスイッチをオンに戻します。

if ($count > 0) { 
    $connect->query('TRUNCATE `table`'); 

    //check toperform operation 

    foreach ($jsondecode as $entries) { 

     //getting variables here 

     $sql = "INSERT INTO `table` (title, handle, imagesrc) 
     VALUES ('".$title."', '".$handle."', '".$imagesrc."')"; 

     if ($connect->query($sql) === TRUE) { 
      echo "New record created successfully"; 
     } else { 
      echo "Error: " . $sql . "<br>" . $connect->error; 
     } 

    } 
} 
+0

返事をありがとう。あなたは精緻化できますか?私はこの周りに頭を包み込みたいと思っています。あなたは理由が1人の余分なキャラクターの存在であると言いますか?あなたはどんなキャラクターについて話していますか?何かをインデントする必要がありますか?また、TRUNCATE文はループ外(IF文の後、FOREACHループの前)で実行されます。私は単一の挿入クエリで作業中ですが、それは時間がかかります。誰もが助けてくれてありがとう – bbruman

+0

これは、私はマルチクエリを使用する必要がありますが、ループの外でTRUNCATEクエリを実行すると言うことではないと言っている...そして、ループ内の別のINSERTクエリ?それは2つの複数のステートメントです....私は、このMULTI_QUERYのような2つのステートメントを私の唯一の選択肢とする印象を受けましたか? – bbruman

+0

これらは複数のクエリではありません。 phpmysadminまたはmysql consoleに異なるクエリを入力できるのと同じように、最初のバージョンとまったく同じように、クエリを1つずつ渡すことができます。 – e4c5

関連する問題