Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Importar arquivo CSV grande para o MySQL


tente otimizar seus scripts primeiro. Em primeiro lugar, nunca execute consultas únicas ao importar, a menos que você não tenha outra escolha, a sobrecarga da rede pode ser um assassino.

Tente algo como (obviamente não testado e codificado na caixa de texto SO, verifique os colchetes correspondem 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);
}

Brinque com o número em array_chunk, muito grande e pode causar problemas como a consulta ser muito longa (sim, há um limite configurável em my.cnf), muito pequeno e sua sobrecarga desnecessária.

Você também pode descartar o uso de atribuir $data[x] a variáveis, pois é um desperdício, dado o tamanho do script, basta usar o $data[x] diretamente em sua consulta e.c.t. (não vai dar uma grande melhoria, mas dependendo do tamanho da importação pode economizar um pouco).

A próxima coisa seria usar inserções/atualizações de baixa prioridade, confira isso para obter mais informações sobre isso para começar:Como dar prioridade a determinadas consultas?

depois de tudo isso, você pode pensar na otimização de configuração do mysql, mas isso é para o google explicar realmente, pois as melhores configurações são diferentes para todos e suas situações únicas

Editar: Outra coisa que fiz antes é se você tiver muitas chaves configuradas que não são necessárias para a importação, você pode descartar essas chaves temporariamente e adicioná-las de volta quando o script estiver concluído. Isso também pode render boas melhorias de tempo, mas como você está trabalhando em um banco de dados ativo, há armadilhas para contornar se você seguir esse caminho.