Pagina 1 di 4 1 2 3 ... ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 32
  1. #1
    Utente di HTML.it
    Registrato dal
    Oct 2004
    Messaggi
    102

    Uscita anomala da ciclo while con tabella enorme

    Ciao a tutti, da giorni ho una tabella che è cresciuta in modo esponenziale.

    Contiene 12.850.000 record ed è composta da un solo campo di tipo text.

    Ho creato un ciclo while che effettua delle operazioni ad ogni record letto.

    Il grave problema è che ad un certo punto ( ogni volta su record diversi quindi non si può impurate ad un record sporco o a specifiche anomalie del tracciato record) senza segnalare errori esce dal ciclo anticipatamente lasciando così a metà l'opera!

    E' come se non ce la facesse con le risorse del server ad eseguire tutto il ciclo.

    questo lo script:
    Codice PHP:
    $query_rst_schede "SELECT * FROM appo_1_cartelle ";
    $dati=mysqli_query($link1$query_rst_schedeMYSQLI_USE_RESULT) or die("Errore Query - 1");

    while(
    $array=mysqli_fetch_array($dati))    {
            
    $carx_codut2  addslashes(substr($array['campo'],3,2));
            
    $carx_cf addslashes(substr($array['campo'],81,16));
            
    $carx_codprov addslashes(substr($array['campo'],58,3));
            
    $carx_codcom addslashes(substr($array['campo'],61,3));
            
    $carx_emisced addslashes(substr($array['campo'],64,7));

            
    $query_rst_anagr "
            SELECT anagrafica.ana_codut2, anagrafica.ana_cf, anagrafica.IDana
            FROM anagrafica
            WHERE anagrafica.ana_codut2 =  '
    $carx_codut2
            AND anagrafica.ana_cf = '
    $carx_cf'
             "
    ;
            
    $dati_anagr=mysqli_query($link$query_rst_anagr) or die("Errore Query - conc");
            
    $array_anagr=mysqli_fetch_assoc($dati_anagr);
            
    $IDana $array_anagr['IDana'];
            
    mysqli_free_result($dati_anagr);
        
        
            
    $query_rst_carte "
            SELECT cartelle.IDCart, cartelle.car_codprov, cartelle.car_codcom, cartelle.car_emisced
            FROM cartelle
            WHERE cartelle.car_codprov = '
    $carx_codprov'
            AND cartelle.car_codcom = '
    $carx_codcom
            AND cartelle.car_emisced = '
    $carx_emisced'
             "
    ;
            
    $dati_carte=mysqli_query($link$query_rst_carte) or die("Errore Query - carte");
            
    $array_carte=mysqli_fetch_assoc($dati_carte);
            
    $IDCart $array_carte['IDCart'];
            
    mysqli_free_result($dati_carte);

            if(
    $IDana){        
                if(
    $IDCart){

                    
    $query_rst_re1 mysqli_query($link"
                    UPDATE cartelle 
                    SET
                    car_host = '1'
                    WHERE cartelle.car_codprov = '
    $carx_codprov'
                    AND cartelle.car_codcom = '
    $carx_codcom
                    AND cartelle.car_emisced = '
    $carx_emisced'
                    "
    ) or die("Errore query UPDATE cartelle filtro ");

                }
            }    
        }
    }
    mysqli_free_result($dati); 
    Ho usato MYSQLI_USE_RESULT perchè senza non riusciva a caricare la query.

    Importante!!! Chiaramente è una procedura batch eseguita da linea di comando DOS.
    - Testata su Windows Server 2003 e 2008 con MySql commerciale Enterprise e PHP 5.3.
    - Tabella testata sia come MyIsam che Innodb.
    - Le tabelle sono tutte indicizzate.
    Tutto con lo stesso risultato anomalo.

    Grazie anticipatamente. Attendo con ansia

  2. #2
    molto probabilmente ... va in timeout il codice

    il problema, comunque, è di php non di mysql

    sposto lì
    The fastest Redis alternative ... cachegrand! https://github.com/danielealbano/cachegrand

  3. #3
    ma sei sicuro che fare 25 milioni e 700 mila query, senza contare quelle di update, sia una buona idea? mi sa che ti tocca spostare il tutto nel database o limitare il numero di dati da elaborare ad ogni esecuzione del batch
    IP-PBX management: http://www.easypbx.it

    Old account: 2126 messages
    Oldest account: 3559 messages

  4. #4
    Utente di HTML.it
    Registrato dal
    Oct 2004
    Messaggi
    102
    Originariamente inviato da Santino83_02
    ma sei sicuro che fare 25 milioni e 700 mila query, senza contare quelle di update, sia una buona idea? mi sa che ti tocca spostare il tutto nel database o limitare il numero di dati da elaborare ad ogni esecuzione del batch
    Necessariamente devo utilizzare questa struttura in quanto
    si tratta di un flusso in arrivo dall'esterno che deve aggiornare tabelle di servizio.

  5. #5
    Originariamente inviato da Botola59
    Necessariamente devo utilizzare questa struttura in quanto
    si tratta di un flusso in arrivo dall'esterno che deve aggiornare tabelle di servizio.

    ma mettere dei trigger nel database che facciano questo no?
    IP-PBX management: http://www.easypbx.it

    Old account: 2126 messages
    Oldest account: 3559 messages

  6. #6
    Utente di HTML.it
    Registrato dal
    Jan 2011
    Messaggi
    1,469
    Originariamente inviato da Santino83_02
    ma mettere dei trigger nel database che facciano questo no?
    ottimo suggerimento.

    ma non solo: perchè fai tutte quelle query separate, invece di una singola update?

    tra l'altro parrebbe che sia irreversibile (=una volta marchiata con 1), e quindi non vedo grandissimi problemi a pre-marchiare, che poi significa "pre-filtrare" le righe "padre", se proprio vuoi utilizzare il tuo approccio.

    Poi perchè un campo text? Così, giusto per curiosità, visto che non vengono proprio gestiti al meglio (eufemisticamente)

  7. #7
    Utente di HTML.it
    Registrato dal
    Oct 2004
    Messaggi
    102
    Originariamente inviato da Santino83_02
    ma mettere dei trigger nel database che facciano questo no?
    Sicuramente dovrò tenere in considerazione la questione trigger;
    materia che però non mai approcciato e per cui non so da dove cominciare.
    Hai qualche link da suggerire per un avvio veloce? Grazie

  8. #8
    Utente di HTML.it
    Registrato dal
    Oct 2004
    Messaggi
    102
    Originariamente inviato da franzauker
    ottimo suggerimento.

    ma non solo: perchè fai tutte quelle query separate, invece di una singola update?

    tra l'altro parrebbe che sia irreversibile (=una volta marchiata con 1), e quindi non vedo grandissimi problemi a pre-marchiare, che poi significa "pre-filtrare" le righe "padre", se proprio vuoi utilizzare il tuo approccio.

    Poi perchè un campo text? Così, giusto per curiosità, visto che non vengono proprio gestiti al meglio (eufemisticamente)
    La mie conoscenze in php e in mysql (molto scarse in mysql) mi hanno portato
    ad approcciare il problema specifico nel modo che puoi vedere schematizzato nello script.

    In definitiva devo aggiornare la tabella "cartelle" con un flag solo nel caso che il record
    contenuto nel flusso "appo_1_cartelle" contenga un campo che agganci la tabella "anagrafica" e
    contestualmente anche la stessa tabella "cartelle".

    Solo adesso comunque rilanciando la procedura che esegue un Mysqlimport leggo che non riesce ad effettuare il LOAD DATA "skippando" tutti i record e lasciandomi la tabella appo_1_cartelle completamente vuota.
    Grazie

  9. #9
    Utente di HTML.it
    Registrato dal
    Jan 2011
    Messaggi
    1,469
    Originariamente inviato da Botola59
    La mie conoscenze in php e in mysql (molto scarse in mysql) mi hanno portato
    ad approcciare il problema specifico nel modo che puoi vedere schematizzato nello script.
    Per la verità non ci ho capito un granchè, di come vuoi operare.
    Sentiti libero di usare "pseudo codice"
    In definitiva devo aggiornare la tabella "cartelle" con un flag solo nel caso che il record
    contenuto nel flusso "appo_1_cartelle" contenga un campo che agganci la tabella "anagrafica" e
    contestualmente anche la stessa tabella "cartelle".
    non so cosa sia per te un "flusso", immagino un file di testo?
    e per "agganci" immagino che intenderai "join"?

    Ma, soprattutto, quando aggiorni il famoso flag, questo rimane settato per sempre?
    ---
    da quanto posso vagamente intuire vuoi
    1) smazzare una tabella gigante per estrarre non so cosa
    2) cercare in una tabella più piccola parti di 1)
    3) cercare in un'altra tabella più piccola altre parti
    4) impostare un flag in un'altra tabella ancora a seconda dei risultati?

    Vabbè per qualcosa di vagamente utile ti suggerisco di postare un dump di un po' di righe delle varie tabelle, e magari anche cosa vuoi ottenere.

    Perchè, se riesco a "decifrare" cosa vuoi fare, spesso basta invertire 4-3-2-1 anzichè il contrario, ossia valutando la cardinalità delle tabelle.
    Se la tabella da settare ha 10 righe (4), mentre la 1 ne ha 10.000.000, può aver senso fare la "back propagation"

  10. #10
    Utente di HTML.it
    Registrato dal
    Oct 2004
    Messaggi
    102
    Originariamente inviato da franzauker
    Per la verità non ci ho capito un granchè, di come vuoi operare.
    Sentiti libero di usare "pseudo codice"

    non so cosa sia per te un "flusso", immagino un file di testo?
    e per "agganci" immagino che intenderai "join"?

    Ma, soprattutto, quando aggiorni il famoso flag, questo rimane settato per sempre?
    ---
    da quanto posso vagamente intuire vuoi
    1) smazzare una tabella gigante per estrarre non so cosa
    2) cercare in una tabella più piccola parti di 1)
    3) cercare in un'altra tabella più piccola altre parti
    4) impostare un flag in un'altra tabella ancora a seconda dei risultati?

    Vabbè per qualcosa di vagamente utile ti suggerisco di postare un dump di un po' di righe delle varie tabelle, e magari anche cosa vuoi ottenere.

    Perchè, se riesco a "decifrare" cosa vuoi fare, spesso basta invertire 4-3-2-1 anzichè il contrario, ossia valutando la cardinalità delle tabelle.
    Se la tabella da settare ha 10 righe (4), mentre la 1 ne ha 10.000.000, può aver senso fare la "back propagation"
    Hai ragione. Andiamo nel dettaglio e con termini più appropriati.

    Il flusso è un file di testo ed ha capienza di 13.000.000 di record.
    Io lo importo con mysqlimport su una tabella a campo unico di tipo text di nome appo_1_cartelle.

    Il ciclo deve leggere tutti questi record di appo_1_cartelle,
    - fare la join sulla tabella anagrafica indicizzata sui campi WHERE (500.000 record);
    - fare la join sulla tabella cartelle indicizzata sui campi WHERE (13.000.000 record);
    - se le join sono riuscite su entrambe le tabelle fare l'update sulla tabella cartelle
    settando il flag car_host a '1' in modo permanente.

    Come posso fornirti il dump delle tabelle?

    Spero di essere stato chiaro - grazie

    PS - Questo il messaggio di errore nell'import:
    codice:
    S:\MySQL\MySQL Server 5.0\bin>mysqlimport  -u root -pxxxxxx --local xxxxx 
    S: \Flussi\Input\cartelle.txt xxxxxx.cartelle: 
    Records: 12850965  Deleted: 0  Skipped: 12850965  Warnings: 295 572193

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.