Visualizzazione dei risultati da 1 a 8 su 8
  1. #1
    Utente di HTML.it
    Registrato dal
    Nov 2008
    Messaggi
    209

    Ottimizzare importazione file pesanti

    Salve a tutti.
    Sto lavorando su un processo di aggiornamento di un'anagrafica articoli.
    I dati degli articoli sono memorizzati in un database mysql e l'utente deve avere la possibilità di aggiornare questi dati caricando sul server dei file di aggiornamento (si tratta di file di testo con un formato predefinito).
    Sono riuscito ad ottenere un processo già funzionante ma ciò che mi lascia perplesso sono i tempi: 11secondi per aggiornare 100 record quando in totale occorre analizzarne 65.000, fatti due conti il sistema impiega circa due ore per analizzare il tutto.
    Sicuramente c'è un modo più efficente di procedere, ecco perchè chiedo la vostra opinione.

    Il processo di aggiornamento, attualmente funziona così:
    c'è un file index.php che richiama via ajax un file updater.php il quale gli risponde e gli passa i dati necessari a tracciare il progresso dell'operazione.
    il file updater.php è quello che analizza il file e procede in questo modo:
    -apre il file
    -ottiene le righe con explode("\n")
    -in un ciclo for vengono analizzate le righe ottenute con explode ma non tutte, solo 100 alla volta
    -nel ciclo ogni riga viene spezzata in base al separatore : explode("-")
    -a questo punto faccio le query di aggiornamento
    -finito di analizzare le 100 righe, il file stampa la stringa con le informazioni sullo stato del processo
    finchè ci sono record da elaborare update.php continua a tornare una stringa, pertanto quando smette di farlo la sequenza di chiamate ajax cessa.
    Il problema risiede nel fatto che devo ogni volta aprire un file del peso di 3MB e 65.000

    Ho anche provato a memorizzare i file nel database alla prima chiamata e leggere i dati dagli stessi per non aprire ogni volta il file ma i tempi sono rimasti pressochè invariati.
    Che altro potrei fare?
    Grazie

  2. #2
    Utente di HTML.it L'avatar di badaze
    Registrato dal
    Jun 2002
    residenza
    Lyon
    Messaggi
    5,372
    Testi l'esistenza dell'articolo prima di creare o aggiornare ? Se è il caso hai un indice sul codice articolo ?
    Ridatemi i miei 1000 posts persi !!!!
    Non serve a nulla ottimizzare qualcosa che non funziona.
    Cerco il manuale dell'Olivetti LOGOS 80B - www.emmella.fr

  3. #3
    11 secondi per 100 record?!? ...

    hum... prova a fart dire quanto ci mette ad eseguire la query di update, magari causa un db poco ottimizzato le condizioni di where richiedono un lungo tempo per eseguire la query... nel qual caso, indicizza correttamente i campi della where, soprattutto se sono stringhe

    il resto dello script non è che l'abbia capito molto sinceramente, cmq invece di aprire e chiudere il file ogni volta mettiti in blocco i dati nel database, probabilmente è più comodo
    IP-PBX management: http://www.easypbx.it

    Old account: 2126 messages
    Oldest account: 3559 messages

  4. #4
    Utente di HTML.it
    Registrato dal
    Nov 2008
    Messaggi
    209
    Nel frattempo ho fatto alcune modifiche:
    -la prima volta leggo il contenuto del file e lo inserisco come stringa nel database, sostituendo gli \n con un separatore |||, in questo modo evito a php di aprire il file ogni volta (a parità di lunghezza dovrebbe metterci meno a leggere una stringa da un database che ad aprire un file, giusto?)
    -faccio la query per ottenere la stringa dal database
    -suddivido la stringa con explode("|||")
    -analizzo 100 record alla volta con un ciclo for
    -finito il ciclo, se ci sono altri record faccio in modo che index.php richiami update.php per fargli fare i prossimi 100 records

    @badaze: si, se l'articolo è presente l'aggiorno con un UPDATE, se non c'è lo aggiungo con INSERT, tuttavia al momento ho disabilitato queste query per vedere se sono responsabili del rallentamento. Ma visto che i tempi sono invariati, non è così

    @Santino83_02: prima di leggere il tuo post ho seguito il tuo consiglio mettendo il file nel database, le query le ho disabilitate temporaneamente ma il problema persiste, quindi sta da un'altra parte.
    Cosa non hai capito dei passaggi? Vuoi vedere il codice?

    @raven74: c'è un solo file di 3MB, niente di più

    Mi sa che il collo di bottiglia è in questo passaggio:
    $rows = explode("|||",$cont);
    perchè, prendendo la stringa completa dal DB e suddividendola in questo modo, ottengo un array di 65.000 elementi!
    Ora sto lavorando sul leggere solo una porzione della stringa dal database, più precisamente quella corrispondente a 100 record, considerando che i record sono a lunghezza fissa, con due calcoli posso tagliarla con precisione

  5. #5
    Utente di HTML.it
    Registrato dal
    Nov 2008
    Messaggi
    209
    Intendi a livello di query?

    codice:
    $start =0;
    $length=55;
    
    for(...){
    $query="SELECT SUBSTRING(contenuto,$start,$length) FROM aggiornamenti";
    $start+=$length;
    }
    Ammetto di non averci proprio pensato, mi sa che ho bisogno di ferie

  6. #6
    Utente di HTML.it L'avatar di badaze
    Registrato dal
    Jun 2002
    residenza
    Lyon
    Messaggi
    5,372
    Dovresti mettere degli echo con l'ora corrente per vedere quale operazione impiega più tempo.

    Poi dipende quante volte fai l'aggiornamento. Se è una volta alla settimana (ad esempio il week end) i tempi sono accettabili se è una volta al giorno .
    Ridatemi i miei 1000 posts persi !!!!
    Non serve a nulla ottimizzare qualcosa che non funziona.
    Cerco il manuale dell'Olivetti LOGOS 80B - www.emmella.fr

  7. #7
    Utente di HTML.it L'avatar di badaze
    Registrato dal
    Jun 2002
    residenza
    Lyon
    Messaggi
    5,372
    E se tu mettessi un ; al posto del | e usassi l'import in una tabella temporanea da file csv ? (Non ho mai provato)
    Ridatemi i miei 1000 posts persi !!!!
    Non serve a nulla ottimizzare qualcosa che non funziona.
    Cerco il manuale dell'Olivetti LOGOS 80B - www.emmella.fr

  8. #8
    Utente di HTML.it L'avatar di boots
    Registrato dal
    Oct 2012
    Messaggi
    1,626
    Non ho ben capito perchè mettere sto file nel db dovrebbe essere più veloce che leggerlo da filesystem (soprattutto se il dbms risiede su una macchina diversa)

    Secondo potresti rendere ogni "blocco" del tuo file di dimensione fissa, in modo che ti puoi spostare agilmente nel file con la fseek. Leggi, come ti hanno suggerito, con la fgets i tuoi 100 record e poi fai la explode.

    In questo modo la lettura del file dovrebbe essere più veloce a discapito però delle dimensioni del file (visto sarà di dimensione fissa, per alcuni record ci saranno spazi vuoti per raggiungere la dimensione fissata )

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.