2010-01-04 14 views
9

Quando eseguo una determinata stored procedure per la prima volta, sono necessari circa 2 minuti per terminare. Quando lo eseguo per la seconda volta, è finito in circa 15 secondi. Presumo che ciò avvenga perché tutto viene memorizzato nella cache dopo la prima esecuzione. È possibile per me "scaldare la cache" prima di eseguire questa procedura per la prima volta? Le informazioni memorizzate nella cache vengono utilizzate solo quando richiamo la stessa stored procedure con gli stessi parametri o verrà utilizzata se chiamo la stessa stored procedure con parametri diversi?Domanda cache cache SQL

risposta

9

Quando si esegue la richiesta, i dati vengono letti in memoria in blocchi. Questi blocchi rimangono in memoria ma vengono "invecchiati". Ciò significa che i blocchi sono etichettati con l'ultimo accesso e quando Sql Server richiede un altro blocco per una nuova query e la memoria cache è piena, il blocco meno recente utilizzato (il più vecchio) viene espulso dalla memoria. (Nella maggior parte dei casi, i blocchi di scansione delle tabelle complete vengono istantaneamente invecchiati per evitare che scansioni complete della tabella possano sovraccaricare la memoria e soffocare il server).

Ciò che sta accadendo qui è che i blocchi di dati in memoria dalla prima query non sono stati espulsi dalla memoria, tuttavia possono essere utilizzati per la seconda query, il che significa che l'accesso al disco è evitato e le prestazioni sono migliorate.

Quindi la tua domanda è davvero chiedere "posso ottenere i blocchi di dati che ho bisogno in memoria senza leggerli in memoria (in realtà facendo una query)?". La risposta è no, a meno che non si desideri memorizzare nella cache le tabelle complete e conservarle permanentemente in memoria che, dal momento della query (e quindi dalla dimensione dei dati) che si sta descrivendo, probabilmente non è una buona idea.

La soluzione migliore per il miglioramento delle prestazioni è esaminare i piani di esecuzione delle query e verificare se la modifica degli indici potrebbe fornire un risultato migliore. Ci sono due aree principali che possono migliorare le prestazioni qui:

  • creando un indice in cui la query potrebbe utilizzare uno per evitare query inefficienti e scansione completa della tabella
  • aggiungendo più colonne a un indice di evitare una seconda lettura del disco. Ad esempio, hai una query che restituisce le colonne A e B con una clausola where su A e C e hai un indice sulla colonna A. La tua query utilizzerà l'indice per la colonna A che richiede una lettura del disco ma richiede un secondo disco colpire per ottenere le colonne B e C. Se l'indice ha tutte le colonne A, B e C in esso il secondo disco colpito per ottenere i dati può essere evitato.
-1

Il piano di esecuzione (le informazioni memorizzate nella cache per la procedura) viene riutilizzato ogni volta, anche con parametri diversi. È uno dei vantaggi dell'utilizzo di stored procs.

La prima volta che viene eseguita una stored procedure, SQL Server genera un piano di esecuzione e lo inserisce nella cache della procedura.

Alcune modifiche al database possono attivare un aggiornamento automatico del piano di esecuzione (ed è anche possibile richiedere esplicitamente una ricompilazione).

I piani di esecuzione vengono eliminati dalla cache delle procedure in base alla loro "età". (da MSDN: gli oggetti raramente referenziati sono presto idonei per deallocation, ma non vengono effettivamente deallocati a meno che la memoria non sia richiesta per altri oggetti.)

Non penso ci sia alcun modo per "riscaldare la cache", eccetto per eseguire il processo memorizzato una volta. Ciò garantirà l'esistenza di un piano di esecuzione nella cache e le eventuali chiamate successive lo riutilizzeranno.

informazioni più dettagliate sono disponibili nella documentazione MSDN: http://msdn.microsoft.com/en-us/library/ms181055(SQL.90).aspx

+4

La vostra risposta, anche se non riesco a vedere niente di sbagliato con esso, non coglie il punto. La compilazione delle query non richiede 1m45s, quindi questo non è il problema dell'OP. I problemi di memorizzazione nella cache degli OP hanno a che fare con la cache della pagina di dati, non con la cache del piano di esecuzione. – erikkallen

3

non credo che genera il piano di esecuzione costerà più di 1 secondo.

Credo che la differenza tra prima e seconda esecuzione sia causata dalla memorizzazione nella cache dei dati in memoria.

I dati nella cache possono essere riutilizzati da qualsiasi ulteriore query (stored procedure o semplice selezione).

È possibile "riscaldare" la cache leggendo i dati tramite qualsiasi selezione che legge gli stessi dati. Ma anche costerà circa 90 secondi.

2

È possibile controllare il piano di esecuzione per individuare le tabelle e gli indici utilizzati dalla query. È quindi possibile eseguire alcuni SQL per ottenere i dati nella cache, a seconda di ciò che si vede.

  • Se si vede un indice cluster cercano, si può semplicemente fare SELECT * FROM my_big_table per forza tutte le pagine di dati della tabella nella cache.
  • Se viene visualizzato un indice senza cluster, è possibile provare SELECT first_column_in_index FROM my_big_table.

Per forzare il caricamento di un indice specifico, è inoltre possibile utilizzare il suggerimento di tabella WITH(INDEX(index)) nelle query di riscaldamento della cache.