Domanda

Sono un rapporto sviluppatore che vuole fare le mie domande il più efficiente possibile. Ho usato per lavorare con un DBA che mi ha detto - credo perché ero sempre a che fare con i rapporti su un server di produzione - ad uso NOLOCK in ogni singola query.

Ora, io lavoro con un DBA che ha bandito NOLOCK in qualsiasi circostanza - anche quando un rapporto di mine (a causa di una notevole mancanza di indici su un paio di tavoli) è fermare gli aggiornamenti di replica e di sistema. A mio parere, in questo caso, un NOLOCK sarebbe una buona cosa.

Poiché la maggior parte della mia formazione SQL è venuto vari amministratori di database con opinioni molto diverse, volevo chiedere questo per una vasta gamma di amministratori di database.

È stato utile?

Soluzione

Se i blocchi del report aggiornamenti che il DBA è giusto: si deve assolutamente usare NOLOCK. Il fatto stesso che ci sono conflitti è una chiara indicazione che se si farebbe uso sporco legge si otterrebbe rapporti non corretti.

A mio parere, ci sono sempre alternative migliori rispetto NOLOCK:

  • I vostri tabelle di produzione di sola lettura a tutti gli effetti e non vengono mai modificati? Contrassegnare il database di sola lettura!
  • Tabella analizza causare conflitti di blocco? Indice delle tabelle in modo appropriato, i benefici sono molteplici.
  • Non è possibile modificare / non so come indicizzare in modo appropriato? Utilizzare Isolamento dello snapshot .
  • Non è possibile cambiare app per uso snapshot? Accendere Read Committed snapshot !
  • Hai misurato l'impatto delle versioni delle righe e hanno prestazioni prove ha un impatto? Non è possibile indicizzare i dati? e tu sei OK con rapporti non corretti ? Poi almeno fatevi un favore e utilizzare SET TRANSACTION ISOLATION LEVEL , non un accenno di query. Sarà più facile per fissare poi il livello di isolamento invece di modificare ogni query.

Altri suggerimenti

Non è sempre male.

Naturalmente consente di leggere i valori non impegnati (che possono essere rotolato indietro e quindi mai logicamente esistito), così come i fenomeni che permettono ad esempio la lettura dei valori più volte o per niente.

Gli unici livelli di isolamento che la garanzia che non si incontrano tali anomalie sono serializzabile / snapshot. Sotto valori letti ripetibili possono mancare se una riga viene spostato (a causa di un aggiornamento della chiave), prima degli raggiunge scansione questa riga, sotto valori impegnati letti possono essere letti due volte se un aggiornamento della chiave provoca fila letto in precedenza per andare avanti.

Questi problemi sono più propensi a sopportare in nolock però, perché, per impostazione predefinita, a questo livello di isolamento userà un'allocazione ordinata scansione quando si stima che ci sono più di 64 pagine da leggere . Così come la categoria di problemi che sorgono quando le righe si muovono tra le pagine grazie alla chiave dell'indice aggiorna questi allocazione ordinato scansioni sono anche vulnerabili a problemi con divisioni di pagina (dove le righe possono perdere se la pagina appena assegnata è precedente nel file rispetto al punto già scansionato o leggere due volte, se una pagina già digitalizzata è diviso su una pagina successiva nel file).

Almeno per semplice (singola tabella) interroga è possibile per scoraggiare l'uso di queste scansioni e ottenere una chiave ordinata scansione a nolock con la semplice aggiunta di un ORDER BY index_key per la query in modo che la proprietà Ordered del IndexScan è true.

Ma se l'applicazione di reporting non ha bisogno di figure assolutamente precisi e in grado di tollerare la probabilità maggiore di tali incongruenze che potrebbe essere accettabile.

Ma di certo non si dovrebbe essere serraggio su tutte le query nella speranza che un pulsante magico "turbo". Così come la maggior probabilità di incontrare risultati anomali a quel livello di isolamento o nessun risultato a tutti ( "non poteva continuare la scansione tramite NOLOCK a causa di spostamento dei dati" errore) ci sono anche casi in cui le prestazioni con nolock può essere molto peggio .

I vostri clienti tollerano risultati inconsistenti nei rapporti? Se la risposta è no, non si dovrebbe usare NOLOCK - si possono ottenere risultati errati in concorrenza. Ho scritto alcuni esempi qui , qui , e qui . Questi esempi mostrano uscita incoerente sotto Read Committed e ripetibili LEGGI, ma è possibile modificare e ottenere risultati errati con NOLOCK pure.

La maggior parte delle relazioni che creo non sono eseguiti su dati attuali. La maggior parte dei clienti sono in esecuzione i rapporti sono dati di ieri. Sarebbe la risposta cambiamento se era il caso?

Se questo è il caso, allora si ha un'opzione più possibile:
Invece di correre le vostre domande sul database di produzione e di fare in giro con serrature e NOLOCK, è possibile eseguire i report da una copia del database di produzione.

È possibile impostarlo in modo è automaticamente ripristinato da un backup ogni notte .
A quanto pare i rapporti sono in esecuzione su server sui siti del cliente, quindi non so se la configurazione di questo sarebbe una soluzione praticabile per voi.
(ma poi di nuovo ... Avrebbero dovuto backup comunque, quindi tutto ciò che serve è un po 'di spazio server per ripristinare la loro)

Sono uno sviluppatore in casa, quindi questo è più facile per me, perché ho il pieno controllo sui server e database.

Si può fare questo almeno per i rapporti che hanno bisogno solo i dati di ieri e più anziani. Forse alcuni rapporti dovranno rimanere sul database di produzione, ma almeno si spostare parte del carico in un altro database (o meglio ancora, un altro server).

Ho la stessa situazione al lavoro pure:
Stiamo utilizzando una copia del database di produzione in questo modo per quasi tutta roba di reporting, ma ci sono un paio di domande che richiedono dati di oggi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a dba.stackexchange
scroll top