C'è un modo per forzare un indice a rimanere in memoria con SQL Server 2008?


10

Ho una tabella con diversi milioni di righe, da cui ho bisogno di eseguire alcune query di volta in volta. La prima query sarà in genere piuttosto lenta (circa 10 secondi) e le query successive sono in genere molto più veloci (circa 1 secondo). Dopo alcune ore, ricomincia un ciclo lento / poi veloce.

Ho verificato nel mio piano di esecuzione che tutti gli indici necessari erano presenti e utilizzati in modo appropriato e presumo che la differenza di prestazioni sia dovuta al fatto che l'indice è effettivamente in memoria per le query successive (ho ragione o ci sono altri cause possibili?)

Sto anche eseguendo molte altre query utilizzando anche gli indici, ma quelle query richiedono meno tempo e le loro prestazioni sono meno critiche, quindi sono preoccupato che quegli indici stiano effettivamente spingendo il mio indice critico fuori dalla cache della memoria.

A parte l'ovvia correzione "aggiungi più RAM", ho pensato di eseguire lo script di query fittizie da eseguire ogni ora per forzare l'indice in memoria.

C'è un modo più elegante per farlo? Come un modo per suggerire a SQL Server che se ha memoria sufficiente per mantenere nella cache un singolo indice, dovrebbe essere quello?

So che di solito la cosa migliore non è incasinare quale SQL Server per quel tipo di cose, ma l'insolita natura della mia query (viene eseguita molto raramente, ma critica nel tempo) mi fa credere che avrebbe senso (se possibile) .

Sono anche curioso di sapere se esiste un modo per sapere quali indici sono memorizzati nella cache in un determinato momento?

Risposte:


13

C'era un DBCC PINTABLEcomando, ma credo che abbia smesso di funzionare in 6.5 o forse 7.0. L'affermazione probabilmente suggerirà comunque che ha funzionato se lo provi, ma ritorna, è davvero una no-op.

Sfortunatamente non c'è davvero alcun modo per controllare quali indici vengono mantenuti nella cache: la soluzione alternativa che conosco per le tabelle periodicamente attive è mantenerle attive manualmente (che hai già descritto nella tua domanda).

Per quali indici sono in memoria, puoi avere un'idea approssimativa da sys.sm_os_buffer_descriptors. Ho pubblicato un suggerimento su questo:

http://www.mssqltips.com/sqlservertip/2393/determine-sql-server-memory-use-by-database-and-object/


Hmm, secondo quello script, una tabella da 75 MB occupa 900 MB di pool di buffer. È normale / possibile?
db2,

1
@ db2 quanti indici hai?
JNK,

2
Anche quanto è frammentato ... misura le pagine, non i dati. Le tue pagine possono essere relativamente vuote e ciò può contribuire a una misura gonfiata.
Aaron Bertrand

0

Prova a utilizzare KEEPPLANe KEEPPLAN FIXED interrogare i suggerimenti .

KEEPPLAN impone a Query Optimizer di allentare la soglia di ricompilazione stimata per una query.

KEEPFIXED PLAN impone a Query Optimizer di non ricompilare una query a causa di cambiamenti nelle statistiche. Specificando KEEPFIXED PLAN si assicura che una query verrà ricompilata solo se lo schema delle tabelle sottostanti viene modificato o se sp_recompile viene eseguito su tali tabelle.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.