Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Importieren Sie eine große CSV-Datei in MySQL

Versuchen Sie zuerst, Ihre Skripte zu optimieren. Führen Sie zunächst beim Importieren niemals einzelne Abfragen aus, es sei denn, Sie haben keine andere Wahl, der Netzwerk-Overhead kann ein Killer sein.

Versuchen Sie etwas wie (offensichtlich ungetestet und in das SO-Textfeld codiert, überprüfen Sie, ob die Klammern mit e.c.t. übereinstimmen):

$url = 'http://www.example.com/directory/file.csv';
if (($handle = fopen($url, "r")) !== FALSE) 
{
fgetcsv($handle, 1000, ",");

$imports = array();

while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) 
{
    $EvID = $data[0];
    $Ev = $data[1];
    $PerID = $data[2];
    $Per = $data[3];
    $VName = $data[4];
    $VID = $data[5];
    $VSA = $data[6];
    $DateTime = $data[7];
    $PCatID = $data[8];
    $PCat = $data[9];
    $CCatID = $data[10];
    $CCat = $data[11];
    $GCatID = $data[12];
    $GCat = $data[13];
    $City = $data[14];
    $State = $data[15];
    $StateID = $data[16];
    $Country = $data[17];
    $CountryID = $data[18];
    $Zip = $data[19];
    $TYN = $data[20];
    $IMAGEURL = $data[21];
    $URLLink = $data[22];

        $data[7] = strtotime($data[7]);
        $data[7] = date("Y-m-d H:i:s",$data[7]);

    if((($PCatID == '2') && (($CountryID == '217') or ($CountryID == '38'))) || (($GCatID == '16') or ($GCatID == '19') or ($GCatID == '30') or ($GCatID == '32'))) 
    {

    $imports[] = "('".md5($EventID.$PerformerID)."','".addslashes($data[0])."','".addslashes($data[1])."','".addslashes($data[2])."','".addslashes($data[3])."','".addslashes($data[4])."',
                    '".addslashes($data[5])."','".addslashes($data[6])."','".addslashes($data[7])."','".addslashes($data[8])."','".addslashes($data[9])."',
                '".addslashes($data[10])."','".addslashes($data[11])."','".addslashes($data[12])."','".addslashes($data[13])."','".addslashes($data[14])."',
                    '".addslashes($data[15])."','".addslashes($data[16])."','".addslashes($data[17])."','".addslashes($data[18])."','".addslashes($data[19])."',
                '".addslashes($data[20])."','".addslashes($data[21])."')";



    }
}

$importarrays = array_chunk($imports, 100);
foreach($importarrays as $arr) {

 if(!mysql_query("INSERT IGNORE INTO TNDB_CSV2 
                (id, EvID, Event, PerID, Per, VName,
                     VID, VSA, DateTime, PCatID, PCat,                
                CCatID, CCat, GCatID, GCat, City,
                     State, StateID, Country, CountryID, Zip,
                TYN, IMAGEURL) VALUES ".implode(',', $arr)){

     die("error: ".mysql_error());

 }

 }

fclose($handle);
}

Spielen Sie mit der Zahl in array_chunk herum, sie ist zu groß und kann Probleme verursachen, wie z. B. eine zu lange Abfrage (ja, es gibt eine konfigurierbare Grenze in my.cnf), eine zu kleine und unnötige Mehrkosten.

Sie könnten auch auf die Verwendung von $data[x] zu Variablen verzichten, da dies eine Verschwendung ist, wenn man bedenkt, wie klein das Skript ist. Verwenden Sie einfach $data[x] direkt in Ihrer Abfrage e.c.t. (Wird keine massive Verbesserung bringen, aber je nach Importgröße könnte es ein wenig sparen).

Als Nächstes würden Sie Einfügungen/Updates mit niedriger Priorität verwenden. Weitere Informationen dazu finden Sie hier, um Ihnen den Einstieg zu erleichtern:Wie gebe ich bestimmten Abfragen Priorität?

nach all dem könnte man an mysql-konfigurationsoptimierungen denken, aber das muss google wirklich erklären, da die besten einstellungen für jeden und seine einzigartigen situationen unterschiedlich sind

Bearbeiten: Eine andere Sache, die ich zuvor getan habe, ist, wenn Sie viele Schlüssel eingerichtet haben, die für den Import nicht erforderlich sind, können Sie diese Schlüssel vorübergehend löschen und sie wieder hinzufügen, wenn das Skript fertig ist. Dies kann auch zu guten Zeitverbesserungen führen, aber da Sie an einer Live-Datenbank arbeiten, gibt es Fallstricke, die Sie umgehen müssen, wenn Sie diesen Weg einschlagen.