Existe uma maneira de forçar um índice a permanecer na memória com o SQL Server 2008?

10

Eu tenho uma tabela com vários milhões de linhas, da qual preciso executar algumas consultas periodicamente. A primeira consulta geralmente será bastante lenta (cerca de 10s) e as consultas subsequentes geralmente são muito mais rápidas (cerca de 1s). Após algumas horas, um ciclo lento / rápido começa novamente.

Eu verifiquei no meu plano de execução se todo o índice necessário estava presente e usado apropriadamente e presumo que a diferença de desempenho se deva ao fato de o índice estar realmente na memória para as consultas subseqüentes (estou certo ou há outro Causas Possíveis?)

Também estou executando muitas outras consultas usando índices, mas essas consultas consomem menos tempo e seu desempenho é menos crítico, por isso estou preocupado que esses índices estejam realmente empurrando meu índice crítico para fora do cache de memória.

Além da correção óbvia de 'adicionar mais RAM', estive pensando em consultas fictícias de script a cada hora para forçar o índice de volta à memória.

Existe uma maneira mais elegante de fazer isso? Como uma maneira de sugerir ao SQLServer que, se ele tiver memória suficiente para manter um único índice em cache, deve ser esse?

Eu sei que geralmente a melhor coisa é não atrapalhar o SQLServer com relação a esse tipo de coisa, mas a natureza incomum da minha consulta (é executada muito raramente, mas com tempo crítico) me faz acreditar que faria sentido (se possível) .

Também estou curioso para saber se há uma maneira de saber quais índices são armazenados em cache na memória em um determinado momento?

Brann
fonte

Respostas:

13

Costumava haver um DBCC PINTABLEcomando, mas acredito que parou de funcionar no 6.5 ou 7.0. A declaração provavelmente ainda sugere que funcionou se você tentar, mas apenas retorna, é realmente um no-op.

Infelizmente, não há realmente nenhuma maneira de controlar quais índices são mantidos no cache - a melhor solução que conheço para tabelas que estão periodicamente quentes é mantê-las quentes manualmente (o que você já descreveu na sua pergunta).

Para quais índices estão na memória, você pode ter uma ideia aproximada sys.sm_os_buffer_descriptors. Publiquei uma dica sobre isso:

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

Aaron Bertrand
fonte
Hmm, de acordo com esse script, uma tabela de 75 MB está ocupando 900 MB de buffer pool. Isso é normal / possível?
db2
11
@ db2 quantos índices você tem?
JNK
2
Também quão fragmentado é ... está medindo páginas, não dados. Suas páginas podem estar relativamente vazias e isso pode contribuir para uma medida inflada.
Aaron Bertrand
0

Tente usar KEEPPLANe KEEPPLAN FIXED consultar dicas .

KEEPPLAN força o otimizador de consulta a relaxar o limite de recompilação estimado para uma consulta.

KEEPFIXED PLAN força o otimizador de consulta a não recompilar uma consulta devido a alterações nas estatísticas. A especificação de KEEPFIXED PLAN assegura que uma consulta seja recompilada apenas se o esquema das tabelas subjacentes for alterado ou se sp_recompile for executado nessas tabelas.

StanleyJohns
fonte