none
Sql Server 2014 e Tabelle occupate RRS feed

  • Domanda

  • Buonasera a tutti,

    ho bisogno del vs aiuto:

    ho un db su SQL che viene sincronizzato una/due volte al giorno importando o aggiornando tabelle nel mio db SQL da un file.txt che puo contenere anche 100.000/200.000 record.

    Il problema è che mentre importa, il sito web in asp.net ha delle maschere che interrogano le stesse tabelle, che il contenuto del file .txt sta popolando o aggiornando, e i tempi diventano biblici.

    Come posso fare secondo voi per risolvere il problema che termina ogni qualvolta termina l'importazione del famoso file .txt.
    Nelle maschera da ASP.NET posso andare ad interrogare queste tabelle in un modo particolare più leggero? non so cosa pensare. Attendo vs, con voi ho sempre trovato la soluzione ed anche questa volta son sicuro avverrà cosi


    Emanuele

    venerdì 4 dicembre 2015 17:37

Risposte

  • Duplicare tutte le tabelle è una possibilità che ti impone il disegno di un progetto. Ed è pure solido. Però non sei costretto a fare così per tutto. Potresti accontentarti di scalare il processo come descritto nel mio post precedente solo per le tabelle più onerose.

    Se proprio non vuoi scrivere niente, l'unica cosa che puoi fare senza modificare processi o schema è andare a leggere in READ UNCOMMITTED. Attenzione però, perchè quello che leggi è potenzialmente non consistente (e più le righe sono tante più è possibile). Quindi fai attenzione all'utilizzo che fai delle tue letture.

    Purtroppo sono problematiche che vanno analizzate e gestite in un certo modo. Non c'è una soluzione immediata e semplice per casi come questo, che sono piuttosto articolati.


    Alessandro Alpi - SQL Server MVP CTO at Engage IT Services S.r.l.

    • Contrassegnato come risposta EmanueleVbSql mercoledì 23 dicembre 2015 11:52
    martedì 22 dicembre 2015 10:14
    Moderatore

Tutte le risposte

  • Ciao EmanueleVbSql,

    personalmente non caricherei la stessa tabella che vai a leggere tutto in una singola operazione online. Creerei una struttura (chiamiamola di "staging") identica alla destinazione, constraint compresi (anche creati successivamente al caricamento, giusto per i controlli di integrità referenziale), e andrei acaricare batch i dati in essa.

    Una volta che i dati sono caricati, una bella insert nella tabella di destinazione direttamente dalla select della nuova struttura creata e popolata.

    Questo dovrebbe già farti guadagnare tantissimo, tuttavia ci sono tante tecniche per fare questo tipo di operazioni (bulk operations). Ma per ora parti da qui e vedi se ottieni quello che serve.

    ciao


    Alessandro Alpi - SQL Server MVP CTO at Engage IT Services S.r.l.

    lunedì 14 dicembre 2015 08:21
    Moderatore
  • Ciao e grazie,

    il fatto è che in questione non c'è una sola tabella che viene popolata dalla "sincronizzazione" ma tantissime tabelle, che faccio duplico tutte le tabelle?
    Non c'è un'altro modo?


    Emanuele

    lunedì 14 dicembre 2015 09:11
  • Ciao a tutti,
    ho un db in SQL2014 Enterprise che riceve più volte al giorno un file .TXT con migliaia di record che vanno a fare UPDATE ed INSERT in molte tabelle del db stesso.

    Domanda:
    con asp.net mi collego al db con il quale gli utenti lavorano tutto il giorno (circa 300 utenti), in particolare le maschere che utilizzano le stesse tabelle in SELECT ed UPDATE che vengono interessate dal file .TXT famoso.

    Come posso fare per NON far considerare agli utenti ciò che sta avvenendo con l'importazione del file .TXT ? Posso usare il WITH (NOWAIT) per le select ma per gli Update come faccio??

    Mi date qualche consiglio per favore, anche perchè mi è accaduto che a  volte, mentre importo il file .TXT CADONO le sessioni degli utenti connessi al DB nelle maschere che interrogano le tabelle interessate ( attualmente non ho da nessuna parte il NOWAIT )

    Certo del vs aiuto e della vs professionalità attendo paziente.


    Emanuele

    sabato 19 dicembre 2015 17:20
  • Ciao Emanuele,

    >> Come posso fare per NON far considerare agli utenti ciò che sta avvenendo con l'importazione del file .TXT ?

    purtroppo, o per fortuna :) quando viene eseguita una operazione che modifica i dati dobbiamo fare i conti con i lock. Il consiglio che ti posso dare è quello di cercare di mantenere le transazioni più corte possibile, potresti importare il file TXT all'interno di una tabella temporanea ed effettuare poi il caricamento da quella. Un altro consiglio è quello ci effettuare il caricamento dei dati quando gli utenti non lavoro (se possibile ovviamente).

    Che livello di isolamento viene utilizzato dalla procedura che effettua il caricamento dei dati ?

    Hai valutato di portare quelle tabelle "In-Memory" ?

    >> mi è accaduto che a  volte, mentre importo il file .TXT CADONO le sessioni degli utenti connessi al DB

    Cosa intendi per "Cadono" ? Mi aspetto che gli utenti possano lamentare rallentamenti (dovuti ai lock) durante le operazioni di importazione, ma non mi aspetto che Cadano le sessioni..

    Ciao


    Sergio Govoni

    SQL Server MVP
    MVP Profile | English Blog | Twitter | LinkedIn


    sabato 19 dicembre 2015 23:58
    Moderatore
  • Ciao Sergio e intanto grazie:
    Che livello di isolamento viene utilizzato dalla procedura che effettua il caricamento dei dati ?---> uso il classico modo:
    BEGIN TRANSACTION

    varie Update ed Insert nelle Tabelle leggendo il fiule .TXT

    se va tutto bene:
    COOMIT
    altrimenti
    ROLLBACK

    Hai valutato di portare quelle tabelle "In-Memory" ? ---> Cioè, importare il file .TXT in una tabellona e poi leggere da li per fare le operazioni?

    Cosa intendi per "Cadono" ? ---> Intendo che mentre importa, le maschere .ASPX che leggono con delle select i dati dalle stesse tabelle interessate alla import NON funzionano, a volte gli dà come se fosse andata via la linea Internet ma non è cosi, io credo vadano in timeout visti i tempi di attesa.
    Per questo ti chiedevo se potevo usare il NOWAIT, che ne pensi?

    Purtroppo poi non posso rimandare questa operazione perchè le informazioni che gli passo a metà mattina per esempio gli servono agli utenti per il resto della giornata.

    Io importo il file .TXT con un metodo che importa il file stesso in una Tabella (
    uftReadfileAsTable ) e da lì poi mi leggo record x record e faccio le varie Insert/Update a seconda della necessità.

    Fammi sapere, gentilmente, cosa ne pensi delle cose a cui ti ho risposto, grazie.


    Emanuele

    domenica 20 dicembre 2015 05:03
  • Ciao Emanuele,

    BEGIN TRANSACTION

    varie Update ed Insert nelle Tabelle leggendo il fiule .TXT

    se va tutto bene:
    COOMIT
    altrimenti
    ROLLBACK

    probabilmente la transazione che viene aperta all'inizio del caricamento (elaborazione del file TXT) e committata o respinta al termine di tutte le operazioni, produce un numero di lock tale da bloccare l'operatività degli altri utenti.

    Io cercherei di capire se i record del file TXT possono essere caricati e committati separatamente e non all'interno di un'unica transazione. Mi spiego meglio, se stai importando degli ordini di vendita o dei movimenti contabili e al termine del caricamento di un ordine (testa e righe) o di un movimento contabile si potrebbe chiudere la transazione perché è già stata raggiunta l'atomicità dell'operazione.. bhe allora chiuderei la transazione in modo che SQL Server possa rilasciare i lock che sono stati acquisiti per effettuare le modifiche ai dati. Sostanzialmente dovresti individuare qual è l'elemento atomico nel tuo caricamento ed aprire e chiudere la transazione per ogni operazione.. facendo finta che il file contenga un solo elemento da importare :)

    Questo ridurrà drasticamente il tempo di mantenimento dei lock e gli altri utenti non troveranno le risorse bloccate e potranno quindi lavorare.

    Per questo ti chiedevo se potevo usare il NOWAIT, che ne pensi?

    Non sono un fan degli hint NOWAIT e NOLOCK, preferisco evitare :)

    Probabilmente ti riferivi all'uso di NOLOCK nelle SELECT, utilizzando NOLOCK sostanzialmente la tua query leggerà anche dati non committati (utilizzerà il livello di isolamento readuncommitted), senza parlare degli altri effetti collaterali legati all'utilizzo di questo hint.

    Purtroppo poi non posso rimandare questa operazione perchè le informazioni che gli passo a metà mattina per esempio gli servono agli utenti per il resto della giornata.

    Peccato, immaginavo fosse così :(

    Ciao


    Sergio Govoni

    SQL Server MVP
    MVP Profile | English Blog | Twitter | LinkedIn

    domenica 20 dicembre 2015 11:23
    Moderatore
  • Ciao Sergio,

    purtroppo non posso "spezzere" le COMMIT ( mi fa pure un pò paura la cosa, dovesse andare male le seconda mi ritrovo il dato solo della prima ), anche se il record riguardano N tabelle son tutte collegate, non è semplice la cosa.

    Perchè preferisci evitare NOWAIT ? Il dato che mi sta entrando NON va a toccare ciò su cui loro stanno lavorando quindi NON mi interessa che possano vederlo prima della COMMIT.

    Non so se sia possibile inviarti un msg in privato per spiegarti meglio l'ambito in cui avviene tutto ciò che lavora quasi H24 7 gg su 7.

    Dovesse venirti in mente qualcosa fammi sapere, è un progetto nuovo che è partito con tantissimi clienti che hanno aderito e ci tengo a non deluderli.

    Grazie e buona domenica


    Emanuele

    domenica 20 dicembre 2015 11:40
  • Ciao Emanuele,

    l'hint di tabella NOWAIT fa sì che restituito un messaggio non appena viene rilevato un blocco nella tabella. NOWAIT equivale a specificare SET LOCK_TIMEOUT 0.. la query viene terminata senza attese.

    Presumo che tu non voglia utilizzare l'hint NOWAIT ma NOLOCK che equivale ad utilizzare il livello di isolamento READUNCOMMITTED (= leggi anche i dati non committati).. qui trovi gli effetti collaterali che si possono verificare utilizzando l'hint NOLOCK:

    ..l'importante è esserne consapevoli :)

    Per quanto riguarda l'idea di "spezzare" i COMMIT, ovviamente non intendevo proporti di fare un COMMIT per tabella, ma per operazione atomica.. ad esempio, se stai caricando un ordine di vendita potresti fare una transazione al termine del caricamento di testate e righe e dopo aver aggiornato altre eventuali tabelle collegate. Le righe del file TXT (ordini di vendita nel mio esempio) che generano errori potrebbero essere spostati, ad esempio, in una tabella di log degli errori.

    Verifica inoltre che non ci siano indici non utilizzati (nelle tabelle interessate dalle modifiche) la cui manutenzione allunga il tempo alla transazione.

    Ciao


    Sergio Govoni

    SQL Server MVP
    MVP Profile | English Blog | Twitter | LinkedIn





    domenica 20 dicembre 2015 17:41
    Moderatore
  • Duplicare tutte le tabelle è una possibilità che ti impone il disegno di un progetto. Ed è pure solido. Però non sei costretto a fare così per tutto. Potresti accontentarti di scalare il processo come descritto nel mio post precedente solo per le tabelle più onerose.

    Se proprio non vuoi scrivere niente, l'unica cosa che puoi fare senza modificare processi o schema è andare a leggere in READ UNCOMMITTED. Attenzione però, perchè quello che leggi è potenzialmente non consistente (e più le righe sono tante più è possibile). Quindi fai attenzione all'utilizzo che fai delle tue letture.

    Purtroppo sono problematiche che vanno analizzate e gestite in un certo modo. Non c'è una soluzione immediata e semplice per casi come questo, che sono piuttosto articolati.


    Alessandro Alpi - SQL Server MVP CTO at Engage IT Services S.r.l.

    • Contrassegnato come risposta EmanueleVbSql mercoledì 23 dicembre 2015 11:52
    martedì 22 dicembre 2015 10:14
    Moderatore