2010-01-04 7 views
9

Lorsque j'exécute une certaine procédure stockée pour la première fois, il faut environ 2 minutes pour terminer. Quand je l'ai exécuté pour la deuxième fois, il a fini dans environ 15 secondes. Je suppose que c'est parce que tout est mis en cache après la première exécution. Est-il possible pour moi de "réchauffer le cache" avant d'exécuter cette procédure pour la première fois? Les informations mises en cache ne sont-elles utilisées que lorsque j'appelle à nouveau la même procédure stockée avec les mêmes paramètres ou est-ce que je l'utiliserai si j'appelle la même procédure stockée avec des paramètres différents?Question du cache SQL Server

Répondre

9

Lorsque vous effectuez une requête, les données sont lues en blocs dans la mémoire. Ces blocs restent en mémoire mais ils vieillissent. Cela signifie que les blocs sont marqués avec le dernier accès et lorsque Sql Server requiert un autre bloc pour une nouvelle requête et que le cache mémoire est plein, le bloc le moins récemment utilisé (le plus ancien) est expulsé de la mémoire. (Dans la plupart des cas, les blocs d'analyse de tableaux complets sont instantanément vieillis pour éviter que les analyses de table complètes ne surchargent la mémoire et n'ébranlent le serveur).Ce qui se passe ici, c'est que les blocs de données en mémoire de la première requête n'ont pas encore été expulsés de la mémoire, ce qui peut être utilisé pour votre seconde requête, ce qui signifie que l'accès disque est évité et les performances améliorées. Donc, ce que votre question demande vraiment, c'est: "Puis-je obtenir les blocs de données dont j'ai besoin en mémoire sans les lire en mémoire (en train de faire une requête)?". La réponse est non, sauf si vous voulez mettre en cache les tables entières et les laisser en mémoire de façon permanente, ce qui n'est probablement pas une bonne idée de l'heure de la requête (et donc de la taille des données) que vous décrivez. Le meilleur moyen d'améliorer vos performances consiste à examiner les plans d'exécution de vos requêtes et à vérifier si la modification de vos index peut donner de meilleurs résultats. Il existe deux grands domaines qui peuvent améliorer les performances ici:

  • création d'un index où la requête pourrait utiliser une pour éviter les requêtes inefficaces et analyses complètes de table
  • ajoutant plus de colonnes à un index pour éviter une deuxième lecture de disque. Par exemple, vous avez une requête qui retourne les colonnes A, et B avec une clause where sur A et C et vous avez un index sur la colonne A. Votre requête utilisera l'index pour la colonne A nécessitant un disque lu mais nécessitera un second disque hit pour obtenir les colonnes B et C. Si l'index avait toutes les colonnes A, B et C à l'intérieur du deuxième disque frappé pour obtenir les données peuvent être évités.
-1

Le plan d'exécution (informations mises en cache pour votre procédure) est réutilisé à chaque fois, même avec des paramètres différents. C'est l'un des avantages de l'utilisation de procs stockés.

La toute première fois qu'une procédure stockée est exécutée, SQL Server génère un plan d'exécution et le place dans le cache de procédure.

Certaines modifications de la base de données peuvent déclencher une mise à jour automatique du plan d'exécution (et vous pouvez également demander explicitement une recompilation).

Les plans d'exécution sont supprimés du cache de procédures en fonction de leur «âge». (à partir de MSDN: les objets rarement référencés sont bientôt éligibles pour la désallocation, mais ne sont pas réellement désalloués sauf si la mémoire est requise pour d'autres objets.)

Je ne pense pas qu'il existe un moyen de "réchauffer le cache", sauf pour effectuer le proc stocké une fois. Cela garantira qu'il existe un plan d'exécution dans le cache et tous les appels suivants le réutiliseront.

des informations plus détaillées sont disponibles dans la documentation MSDN: http://msdn.microsoft.com/en-us/library/ms181055(SQL.90).aspx

+4

Votre réponse, bien que je ne vois rien de mal à cela, pas la question. La compilation de requêtes ne prend pas 1m45s, donc ce n'est pas le problème du PO. Les problèmes de mise en cache d'OP ont à voir avec le cache de la page de données, et non avec le cache du plan d'exécution. – erikkallen

3

Je ne pense pas que la génération du plan d'exécution va coûter plus cher que 1 seconde.

Je crois que la différence entre la première et la deuxième exécution est causée par la mise en cache des données dans la mémoire.

Les données dans le cache peuvent être réutilisées par n'importe quelle autre requête (procédure stockée ou sélection simple).

Vous pouvez «chauffer» la mémoire cache en lisant les données via n'importe quelle sélection qui lit les mêmes données. Mais cela va même coûter environ 90 secondes aussi.

2

Vous pouvez vérifier le plan d'exécution pour connaître les tables et les index utilisés par votre requête. Vous pouvez ensuite exécuter du code SQL pour récupérer les données dans le cache, en fonction de ce que vous voyez. Si vous voyez une recherche d'index clusterisée, vous pouvez simplement faire SELECT * FROM my_big_table pour forcer toutes les pages de données de la table dans le cache. Si vous voyez une recherche d'index non clusterisée, vous pouvez essayer SELECT first_column_in_index FROM my_big_table. Pour forcer le chargement d'un index spécifique, vous pouvez également utiliser l'indicateur de table WITH(INDEX(index)) dans vos requêtes de préchauffage de cache.