Mysql
 sql >> Base de données >  >> RDS >> Mysql

Importer un gros fichier CSV dans MySQL

essayez d'abord d'optimiser vos scripts. Tout d'abord, n'exécutez jamais de requêtes uniques lors de l'importation, sauf si vous n'avez pas d'autre choix, la surcharge du réseau peut être mortelle.

Essayez quelque chose comme (évidemment non testé et codé dans la zone de texte SO, vérifiez que les crochets correspondent à e.c.t.):

$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);
}

Jouez avec le nombre dans array_chunk, trop grand et cela peut causer des problèmes comme la requête trop longue (oui, il y a une limite configurable dans my.cnf), trop petit et sa surcharge inutile.

Vous pouvez également abandonner l'utilisation d'assigner le $data[x] aux variables car c'est un gaspillage étant donné la petite taille du script, utilisez simplement le $data[x] directement dans votre requête e.c.t. (ne donnera pas une amélioration massive, mais selon la taille de votre importation, cela pourrait économiser un peu).

La prochaine chose serait d'utiliser des insertions/mises à jour de faible priorité, consultez ceci pour plus d'informations à ce sujet pour vous aider à démarrer :Comment donner la priorité à certaines requêtes ?

après tout cela, vous pourriez penser à l'optimisation de la configuration de mysql, mais c'est une chose que Google doit vraiment expliquer car les meilleurs paramètres sont différents pour chacun et leurs situations uniques

Modifier : Une autre chose que j'ai faite auparavant est que si vous avez configuré de nombreuses clés qui ne sont pas nécessaires pour l'importation, vous pouvez supprimer ces clés temporairement et les rajouter lorsque le script est terminé. Cela peut également apporter de bonnes améliorations de temps, mais comme vous travaillez sur une base de données en direct, il y a des pièges à contourner si vous suivez cette voie.