¿Hay alguna manera de forzar que un índice permanezca en la memoria con SQL Server 2008?

10

Tengo una tabla con varios millones de filas, desde la cual necesito ejecutar algunas consultas de vez en cuando. La primera consulta suele ser bastante lenta (alrededor de 10 segundos), y las consultas posteriores suelen ser mucho más rápidas (alrededor de 1 segundo). Después de algunas horas, un ciclo lento / luego rápido comienza nuevamente.

Verifiqué en mi plan de ejecución que todos los índices necesarios estuvieran presentes y se usaran adecuadamente, y supongo que la diferencia de rendimiento se debe al hecho de que el índice está realmente en la memoria para las consultas posteriores (estoy en lo cierto o hay otro ¿Posibles Causas?)

También estoy ejecutando muchas otras consultas usando índices, pero esas consultas requieren menos tiempo y su rendimiento es menos crítico, por lo que me preocupa que esos índices realmente estén sacando mi índice crítico de la memoria caché.

Además de la solución obvia de 'agregar más RAM', he estado pensando en realizar scripts de consultas ficticias que se ejecutan cada hora para forzar el índice de nuevo en la memoria.

¿Hay alguna forma más elegante de hacer esto? ¿Como una manera de insinuar SQLServer que si solo tiene suficiente memoria para mantener un solo índice en caché, debería ser ese?

Sé que, por lo general, lo mejor es no estropear el servidor SQLServer con respecto a ese tipo de cosas, pero la naturaleza inusual de mi consulta (se ejecuta muy raramente, pero con un tiempo crítico) me hace creer que tendría sentido (si es posible) .

También tengo curiosidad por saber si hay una manera de saber qué índices se almacenan en la memoria caché en un momento dado.

Brann
fuente

Respuestas:

13

Solía ​​haber un DBCC PINTABLEcomando, pero creo que dejó de funcionar en 6.5 o quizás 7.0. La declaración probablemente aún sugiera que funcionó si lo prueba, pero solo regresa, realmente no es una opción.

Desafortunadamente, no hay realmente ninguna forma de controlar qué índices se guardan en la memoria caché: la mejor solución que conozco para las tablas que se calientan periódicamente es mantenerlas calientes manualmente (que ya ha descrito en su pregunta).

Para qué índices están en la memoria, puede obtener una idea aproximada sys.sm_os_buffer_descriptors. Publiqué un consejo sobre esto:

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

Aaron Bertrand
fuente
Hmm, de acuerdo con esa secuencia de comandos, una tabla de 75 MB ocupa 900 MB de agrupación de almacenamiento intermedio. ¿Es eso normal / posible?
db2
1
@ db2 ¿cuántos índices tiene?
JNK
2
También qué tan fragmentado está ... mide páginas, no datos. Sus páginas pueden estar relativamente vacías, y eso puede contribuir a una medida inflada.
Aaron Bertrand
0

Intente usar KEEPPLANy KEEPPLAN FIXED consultar sugerencias .

KEEPPLAN obliga al optimizador de consultas a relajar el umbral de recompilación estimado para una consulta.

PLAN MANTENIDO obliga al optimizador de consultas a no volver a compilar una consulta debido a cambios en las estadísticas. Al especificar KEEPFIXED PLAN se asegura que una consulta se recompilará solo si se cambia el esquema de las tablas subyacentes o si se ejecuta sp_recompile en esas tablas.

StanleyJohns
fuente