2

私は夏の就職活動をしている学生です。私は、何年にもわたって実施された調査のために、Excel から SQL Server データベースへのデータ入力を処理するタスクを与えられました。タスクの概要は次のとおりです。

テーブルは本戦、個人戦、個人戦の3つ。イベントには多くの個々のイベントがあり、個々のイベントには多くの個人があります。私のコードは、最後の 2 つのテーブルのみを考慮しています。

私は 2 つのファイルを読みました。1 つのファイルにはすべての個々のイベントのリストがあり、もう 1 つのファイルにはすべての個人のリストが含まれています。個人のデータは、個人がどのイベントに関連付けられているかを教えてくれます。

私のコードは基本的に個々のイベントを読み取り、関連する個人の 2 番目のファイルを調べます。個人ファイルの各行は、関連付けられている場合は適切なテーブルに挿入され、関連付けられていない場合は新しいファイルに書き込まれます。ファイル全体がトラバースされると、新しいファイルが古いファイルにコピーされ、データベースに既に入力されているデータが削除されます。

このコピーにより、完全な個人ファイルを何度も読み直すだけで、実行時間が 3 分短縮されました。しかし、これに対するより良いアプローチはありますか?私のサンプル データの実行時間は ~47 秒です...理想的にはそれよりも短い時間でお願いします。

どんなに些細なことでも、アドバイスをいただければ幸いです。

編集:これは私が使用しているコードの縮小版です

<?php
//not shown:
//connect to database 
//input event data
//get the id of the event
//open files
$s_handle = fopen($_FILES['surveyfile']['tmp_name'],'r');//open survey file
copy($_FILES['cocklefile']['tmp_name'],'file1.csv');//make copy of the cockle file
//read files
$s_csv = fgetcsv($s_handle,'0',',');

//read lines and print lines
// then input data via sql

while (! feof($s_handle))
{
    $max_index = count($s_csv);
    $s_csv[$max_index]='';
    foreach($s_csv as $val)
    {
        if(!isset($val))
        $val = '';
    }
    $grid_no = $s_csv[0];
    $sub_loc = $s_csv[1];
    /*
    .define more variables
    .*/
    

    $sql = "INSERT INTO indipendant_event" 
        ."(parent_id,grid_number,sub_location,....)"
        ."VALUES ("
        ."'{$event_id}',"
        ."'{$grid_no}',"
        //...
        .");";

    if (!odbc_exec($con,$sql))
    {
        echo "WARNING: SQL INSERT INTO fssbur.cockle_quadrat FAILED. PHP.";
    }
    //get ID
    $sql = "SELECT MAX(ind_event_id)"
    ."FROM independant_event";
    $return =  odbc_exec($con,$sql);
    $ind_event_id = odbc_result($return, 1);
    
    //insert individuals
    $c_2 = fopen('file2.csv','w');//create file c_2 to write to 
    $c_1 = fopen('file1.csv','r');//open the data to read
    $c_csv = fgetcsv($c_1,'0',',');//get the first line of data
    while(! feof($c_1))
    {
        
        for($i=0;$i<9;$i++)//make sure theres a value in each column
        {
            if(!isset($c_csv[$i]))
            $c_csv[$i] = '';
        }
        //give values meaningful names
        $stat_no = $c_csv[0];
        $sample_method = $c_csv[1];
        //....
        
        //check whether the current line corresponds to the current station
        if (strcmp(strtolower($stat_no),strtolower($grid_no))==0)
        {
            $sql = "INSERT INTO fssbur2.cockle"
                ."(parent_id,sampling_method,shell_height,shell_width,age,weight,alive,discarded,damage)"
                ."VALUES("
                ."'{$ind_event_id}',"
                ."'{$sample_method}',"
                //...
                ."'{$damage}');";
            //write data if it corresponds
            if (!odbc_exec($con,$sql))
            {
                echo "WARNING: SQL INSERT INTO fssbur.cockle FAILED. PHP.";
            }     
            $c_csv = fgetcsv($c_1,'0',',');  
        }
        else//no correspondance
        {
            fputcsv($c_2,$c_csv);//write line to the new file
            $c_csv = fgetcsv($c_1,'0',',');//get new line
            continue;//rinse and repeat
        }
    }//end while, now gone through all individuals, and filled c_2 with the unused data
    fclose($c_1);//close files
    fclose($c_2);
    copy('file2.csv','file1.csv');//copy new file to old, removing used data
    $s_csv = fgetcsv($s_handle,'0',',');
}//end while

//close file
fclose($s_handle);
?>
4

2 に答える 2

3

プロセスを完全には理解していないかもしれませんが、CSV全体をデータベーステーブルに挿入してみませんか。これは無駄な作業のように見えるかもしれませんが、おそらく報われるでしょう。最初のインポートが完了すると、DBMSはインデックスを使用してこれらのルックアップを高速化できるため、イベントに関連付けられている個人の検索がはるかに高速になります(ファイルベースの線形トラバーサルと比較して)。正確に言うと、「individual」テーブルには、おそらく「individual_event」テーブルへの外部キーがあります。この外部キーにインデックスを作成する限り、ルックアップは大幅に高速になります(このフィールドを外部キーとして宣言するだけで、SQLサーバーが自動的にインデックスを作成する可能性がありますが、はっきりとは言えません。 tは実際にMSSQLを使用します)。

余談ですが、何枚のレコードについて話しているのですか?数千のレコードを処理している場合、このタイプのものが数秒で実行されることを期待するのは間違いなく合理的です。

于 2011-07-04T09:40:22.793 に答える
2

ファイルからのデータを使用して一時データベースを作成し、一時データベース/テーブルを使用してデータを新しい形式にすることができます。これはおそらく、ルックアップを行う必要があり、エントリに処理済みのフラグを立てる必要がある場合に特に高速に機能します。

于 2011-07-04T09:32:10.347 に答える