1 votes

Chargement anticipé des résultats de la requête SQL dans la mémoire cache

Je me trouve dans la situation suivante :

  • .net 3.5 WinForm client app accédant à SQL Server 2008
  • Certaines requêtes renvoyant des quantités relativement importantes de données sont utilisées assez souvent par un formulaire.
  • Les utilisateurs utilisent SQL Express en local et redémarrent leurs machines au moins une fois par jour.
  • D'autres utilisateurs travaillent à distance sur des connexions réseau lentes.

Le problème est qu'après un redémarrage, la première fois que les utilisateurs ouvrent ce formulaire, les requêtes sont extrêmement lentes et prennent plus ou moins 15 secondes à s'exécuter sur une machine rapide. Par la suite, les mêmes requêtes ne prennent que 3 secondes. Bien sûr, cela est dû au fait qu'aucune donnée n'est mise en cache et qu'elle doit d'abord être chargée à partir du disque.

Ma question :
Serait-il possible de forcer le chargement préalable des données requises dans le cache du serveur SQL ?

Note
Ma première idée était d'exécuter les requêtes en arrière-plan au démarrage de l'application, de sorte que lorsque l'utilisateur démarre le formulaire, les requêtes soient déjà mises en cache et s'exécutent rapidement directement. Cependant, je ne veux pas charger le résultat des requêtes sur le client car certains utilisateurs travaillent à distance ou ont des réseaux lents.
J'ai donc pensé à exécuter les requêtes à partir d'une procédure stockée et à placer les résultats dans des tables temporaires afin que rien ne soit renvoyé.
Il s'est avéré que certains des ensembles de résultats utilisent des colonnes dynamiques, de sorte que je n'ai pas pu créer les tables temporaires correspondantes et que ce n'est donc pas une solution.

Avez-vous une autre idée ?

3voto

SqlRyan Points 14999

Êtes-vous sûr que c'est le plan d'exécution qui est créé ou que c'est la mise en cache de la mémoire du serveur qui se produit ? Il se peut que la première requête charge un grand nombre de données, mais que les requêtes suivantes puissent utiliser les données déjà mises en cache et s'exécutent donc beaucoup plus rapidement. Je n'ai jamais vu un plan d'exécution prendre plus d'une seconde à générer, donc je pense que le plan lui-même n'est pas en cause.

Avez-vous essayé de lancer l'assistant d'optimisation d'index sur votre requête ? Si c'est le plan qui pose problème, peut-être que des statistiques ou un index supplémentaire vous aideront, et l'optimiseur est assez doué pour faire des recommandations.

1voto

Michael Petito Points 5554

Je ne sais pas exactement comment vous exécutez vos requêtes, mais vous pourriez le faire :

SqlCommand Command = /* your command */
Command.ExecuteReader(CommandBehavior.SchemaOnly).Dispose();

L'exécution de votre commande avec le comportement de la commande de schéma uniquement ajoutera SET FMTONLY ON à la requête et font que SQL Server obtient des métadonnées sur l'ensemble des résultats (ce qui nécessite la génération du plan), mais n'exécutera pas la commande .

0voto

D.K. Mulligan Points 2272

Pour réduire la source du problème, vous pouvez toujours utiliser les objets SQL Server dans perfmon pour avoir une idée générale des performances de l'instance locale de SQL Server Express.

Dans ce cas, il est probable que le taux de réponse de la mémoire cache soit plus faible lors de la première requête et plus élevé lors des requêtes suivantes.

Vous pouvez également consulter http://msdn.microsoft.com/en-us/library/ms191129.aspx Il décrit comment vous pouvez configurer une sproc pour qu'elle s'exécute automatiquement au démarrage du service SQL Server. Si vous récupérez les données dont vous avez besoin avec cette sproc, elles resteront peut-être en cache et amélioreront les performances la première fois que les données seront récupérées par l'utilisateur final via votre formulaire.

0voto

Marc Points 2477

En fin de compte, j'ai continué à utiliser l'approche que j'avais essayée en premier lieu : Exécuter les requêtes à partir d'une procédure stockée et placer les résultats dans des tables temporaires afin que rien ne soit renvoyé. Cette procédure stockée de "mise en cache" est exécutée en arrière-plan à chaque fois que l'application démarre.
L'écriture des tables temporaires a juste pris un peu de temps car les ensembles de résultats sont dynamiques.

Merci à tous pour votre aide très rapide sur ce problème !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X