Existe-t-il un moyen de forcer un index à rester en mémoire avec SQL Server 2008?

10

J'ai une table avec plusieurs millions de lignes, à partir de laquelle je dois exécuter de temps en temps des requêtes. La première requête sera généralement assez lente (environ 10 secondes), et les requêtes suivantes sont généralement beaucoup plus rapides (environ 1 seconde). Après quelques heures, un cycle lent / puis rapide recommence.

J'ai vérifié dans mon plan d'exécution que tous les index nécessaires étaient présents et correctement utilisés, et je suppose que la différence de performances est due au fait que l'index est réellement en mémoire pour les requêtes suivantes (ai-je raison ou y en a-t-il d'autres causes possibles?)

J'exécute également de nombreuses autres requêtes à l'aide d'index, mais ces requêtes prennent moins de temps et leurs performances sont moins critiques.Je crains donc que ces index ne poussent mon index critique hors du cache mémoire.

Mis à part le correctif évident «ajouter plus de RAM», j'ai pensé à scripter des requêtes factices à exécuter toutes les heures pour forcer l'index à revenir en mémoire.

Existe-t-il une manière plus élégante de procéder? Comme un moyen d'indiquer à SQLServer que s'il ne dispose que de suffisamment de mémoire pour garder un seul index mis en cache, ce devrait être celui-ci?

Je sais que la meilleure chose à faire est généralement de ne pas gâcher le SQLServer en ce qui concerne ce genre de choses, mais la nature inhabituelle de ma requête (qui s'exécute très rarement, mais à temps critique) me fait croire que cela aurait du sens (si possible) .

Je suis également curieux de savoir s'il existe un moyen de savoir quels index sont mis en cache en mémoire à un moment donné?

Brann
la source

Réponses:

13

Il y avait autrefois une DBCC PINTABLEcommande mais je crois qu'elle a cessé de fonctionner en 6.5 ou peut-être 7.0. La déclaration suggérera probablement toujours que cela a fonctionné si vous l'essayez, mais elle revient juste, c'est vraiment un no-op.

Malheureusement, il n'y a pas vraiment de moyen de contrôler les index qui sont conservés dans le cache - la meilleure solution que je connaisse pour les tables qui sont périodiquement chaudes est de les garder manuellement (ce que vous avez déjà décrit dans votre question).

Pour quels index sont en mémoire, vous pouvez en avoir une idée approximative sys.sm_os_buffer_descriptors. J'ai publié un conseil à ce sujet:

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

Aaron Bertrand
la source
Hmm, selon ce script, une table de 75 Mo occupe 900 Mo de pool de mémoire tampon. Est-ce normal / possible?
db2
1
@ db2 combien d'index avez-vous?
JNK
2
Aussi, comment est-il fragmenté ... il mesure des pages, pas des données. Vos pages peuvent être relativement vides, ce qui peut contribuer à une mesure gonflée.
Aaron Bertrand
0

Essayez d'utiliser KEEPPLANet de KEEPPLAN FIXED demander des conseils .

KEEPPLAN force l'optimiseur de requêtes à assouplir le seuil de recompilation estimé pour une requête.

KEEPFIXED PLAN force l'optimiseur de requêtes à ne pas recompiler une requête en raison de modifications des statistiques. La spécification de KEEPFIXED PLAN garantit qu'une requête ne sera recompilée que si le schéma des tables sous-jacentes est modifié ou si sp_recompile est exécuté sur ces tables.

StanleyJohns
la source