sql >> データベース >  >> RDS >> Mysql

PHPで10万行以上のCSVを処理するにはどうすればよいですか?

    このようなもの(これは100%テストされておらず、実際に機能するには頭のてっぺんから微調整が必​​要な場合があることに注意してください:))

    //define array may (probably better ways of doing this
    $stocks = array(
        1  => 22,
        2  => 23,
        3  => 24,
        4  => 25,
        5  => 26,
        6  => 27,
        7  => 28,
        8  => 29,
        9  => 30,
        10 => 31
    );
    
    $handle = fopen("file.csv", "r")); //open file
    while (($data = fgetcsv($handle, 1000, ";")) !== FALSE) {
        //loop through csv
    
        $updatesql = "UPDATE t SET `value` = ".$data[2]." WHERE   fielddef_id = ".$stocks[$data[0]]." AND product_id = ".$data[1];
       echo "$updatesql<br>";//for debug only comment out on live
    }
    

    コードで商品データを1に設定しているだけなので、最初の選択を行う必要はありません。説明から、商品IDは常に正しく、マップを含むfielddef列だけが正しいように見えます。

    また、ライブの場合は、実際のmysqli実行コマンドを$updatesqlに配置することを忘れないでください。

    実際の使用コードと比較するために(ベンチマークを行うことができます!)これは、アップロードされたファイルのインポーターに使用するコードです(完全ではありませんが、機能します)

    if (isset($_POST['action']) && $_POST['action']=="beginimport") {
                echo "<h4>Starting Import</h4><br />";
                // Ignore user abort and expand time limit 
                //ignore_user_abort(true);
                set_time_limit(60);
                    if (($handle = fopen($_FILES['clientimport']['tmp_name'], "r")) !== FALSE) {
                        $row = 0;
                        //defaults 
                        $sitetype = 3;
                        $sitestatus = 1;
                        $startdate = "2013-01-01 00:00:00";
                        $enddate = "2013-12-31 23:59:59";
                        $createdby = 1;
                        //loop and insert
                        while (($data = fgetcsv($handle, 10000, ",")) !== FALSE) {  // loop through each line of CSV. Returns array of that line each time so we can hard reference it if we want.
                            if ($row>0) {
                                if (strlen($data[1])>0) {
                                    $clientshortcode = mysqli_real_escape_string($db->mysqli,trim(stripslashes($data[0])));
                                    $sitename = mysqli_real_escape_string($db->mysqli,trim(stripslashes($data[0]))." ".trim(stripslashes($data[1])));
                                    $address = mysqli_real_escape_string($db->mysqli,trim(stripslashes($data[1])).",".trim(stripslashes($data[2])).",".trim(stripslashes($data[3])));
                                    $postcode = mysqli_real_escape_string($db->mysqli,trim(stripslashes($data[4])));
                                    //look up client ID
                                    $client = $db->queryUniqueObject("SELECT ID FROM tblclients WHERE ShortCode='$clientshortcode'",ENABLE_DEBUG);
    
                                    if ($client->ID>0 && is_numeric($client->ID)) {
                                        //got client ID so now check if site already exists we can trust the site name here since we only care about double matching against already imported sites.
                                        $sitecount = $db->countOf("tblsites","SiteName='$sitename'");
                                        if ($sitecount>0) {
                                            //site exists
                                            echo "<strong style=\"color:orange;\">SITE $sitename ALREADY EXISTS SKIPPING</strong><br />";
                                        } else {
                                            //site doesn't exist so do import
                                            $db->execute("INSERT INTO tblsites (SiteName,SiteAddress,SitePostcode,SiteType,SiteStatus,CreatedBy,StartDate,EndDate,CompanyID) VALUES 
                                            ('$sitename','$address','$postcode',$sitetype,$sitestatus,$createdby,'$startdate','$enddate',".$client->ID.")",ENABLE_DEBUG);
                                            echo "IMPORTED - ".$data[0]." - ".$data[1]."<br />";
                                        }
                                    } else {
                                        echo "<strong style=\"color:red;\">CLIENT $clientshortcode NOT FOUND PLEASE ENTER AND RE-IMPORT</strong><br />";
                                    }
                                    fcflush();
                                    set_time_limit(60); // reset timer on loop
                                }
                            } else {
                                $row++;
                            }
                        } 
                        echo "<br />COMPLETED<br />";
                    }
                    fclose($handle);
                    unlink($_FILES['clientimport']['tmp_name']);
                echo "All Imports finished do not reload this page";
            }
    

    約10秒で15万行をインポートしました



    1. SQLクエリ少なくとも1つ

    2. MySQLインデックス-この表とクエリによるベストプラクティスは何ですか

    3. 複数のテーブルを接続するためのトリガー

    4. MySQL-列内のカンマ区切りの文字列を並べ替えます