3

こんにちは私は15000行のcsvファイルをインポートする必要があります。fgetcsv関数を使用して、すべての行を解析しています。しかし、毎回タイムアウトエラーが発生します。プロセスが遅すぎて、データが部分的にインポートされています。データのインポートをより速く、より効率的にする方法はありますか?

if(isset($_POST['submit']))
{

 $fname = $_FILES['sel_file']['name'];
 $var = 'Invalid File';
 $chk_ext = explode(".",$fname);

 if(strtolower($chk_ext[1]) == "csv")
 {

     $filename = $_FILES['sel_file']['tmp_name'];
     $handle = fopen($filename, "r");
 $res = mysql_query("SELECT * FROM vpireport");
 $rows = mysql_num_rows($res);
 if($rows>=0)
{
    mysql_query("DELETE FROM vpireport") or die(mysql_error());

    for($i =1;($data = fgetcsv($handle, 10000, ",")) !== FALSE; $i++)
    {
        if($i==1)
        continue;
        $sql = "INSERT into vpireport
                                (item_code,
                                 company_id,
                                 purchase,
                                 purchase_value) 
                                 values
                                (".$data[0].",
                                 ".$data[1].",
                                 ".$data[2].",
                                 ".$data[3].")";
        //echo "$sql";
        mysql_query($sql) or die(mysql_error());
    }
}

 fclose($handle);
?>
 <script language="javascript">
 alert("Successfully Imported!");
 </script>
 <?

問題は、インポートプロセスの間にスタックし、次のエラーが表示されるたびに発生します。

エラー1:致命的なエラー:行175で最大制限時間30秒を超えました。

エラー2:

SQL構文にエラーがあります。1行目の「S」、0,0)'の近くで使用する正しい構文については、MySQLサーバーのバージョンに対応するマニュアルを確認してください。

このエラーは検出できません...

ファイルは毎回部分的にインポートされます。10000行のうち約200300行です。

4

6 に答える 6

3

ページの上部でこれを設定します。

set_time_limit ( 0 )

それはページを際限なく実行させます。ただし、これはお勧めしませんが、他に選択肢がない場合は役に立ちません。

こちらのドキュメントを参照してください。

高速化するには、送信するさまざまなSQLをチェックし、適切なインデックスが作成されているかどうかを確認する必要があります。

ユーザー定義関数を呼び出していて、これらの関数がグローバル変数を参照している場合は、それらの変数を関数に渡し、関数がそれらの渡された変数を参照するようにコードを変更することで、さらに時間を最小限に抑えることができます。グローバル変数の参照は、ローカル変数よりも低速です。

于 2012-05-19T06:10:44.487 に答える
3

csv の 500 行ごとにバッチ更新文字列を作成し、各行で mysql 挿入を実行している場合は一度に実行できます。それはより速くなります。

別の解決策は、オフセットを使用してファイルを読み取ることです。

  1. 最初の 500 行を読み取り、
  2. それらをデータベースに挿入します
  3. csvimporter.php?offset=500 にリダイレクト
  4. 1. ステップに戻り、今度はオフセット 500 から始まる 500 行を読み取ります。

別の解決策は、次のようにタイムアウト制限を 0 に設定することです。

set_time_limit(0);
于 2012-05-19T06:15:07.983 に答える
2

mysql ユーティリティである LOAD DATA INFILE を利用できます。これは fgetcsv よりもはるかに高速です。

詳細については、

http://dev.mysql.com/doc/refman/5.1/en/load-data.html

于 2012-05-19T06:26:06.613 に答える
1

問題:
データをテーブルに INSERT する方法は、パフォーマンスに大きな影響を与えます。レコードごとにサーバーに INSERT リクエストを送信すると、15000 の INSERT リクエストが膨大になります。

解決策: :
mysqldump のようにデータをグループ化する必要があります。あなたの場合、以下のように 15000 ではなく 3 つの挿入ステートメントが必要です。

ループ書き込みの前に:

$q = "INSERT into vpireport(item_code,company_id,purchase,purchase_value)values";

ループ内で、以下のようにレコードをクエリに連結します。

$q .= "($data[0],$data[1],$data[2],$data[3]),";

ループ内で、カウンターが 5000 または 10000 または 15000 であることを確認してから、データをvpireprotテーブルに挿入し、$q をINSERT INTO...再度設定します。
クエリを実行してお楽しみください!!!

于 2012-05-19T07:52:39.023 に答える
1

これを使用するだけです @ phpインポートページの先頭

ini_set('max_execution_time',0);
于 2012-05-19T06:21:11.687 に答える
1

これが 1 回限りの演習である場合、PHPMyAdmin は CSV によるインポートをサポートしています。 import-a-csv-file-to-mysql-via-phpmyadmin

彼はまた、MySQL のLOAD DATA LOCAL INFILE. これは、データをデータベース テーブルにインポートするための非常に高速な方法です。データの読み込み Mysql ドキュメント リンク

編集:

ここにいくつかの疑似コードがあります:

// perform the file upload 
$absolute_file_location = upload_file();

// connect to your MySQL database as you would normally
your_mysql_connection();

// execute the query
$query = "LOAD DATA LOCAL INFILE '" . $absolute_file_location . 
         "' INTO TABLE `table_name`
         FIELDS TERMINATED BY ','
         LINES TERMINATED BY '\n'
         (column1, column2, column3, etc)";
$result = mysql_query($query);

明らかに、インジェクションなどを防ぐために適切な SQL プラクティスを確保する必要があります。

于 2012-05-19T06:23:14.743 に答える