2008-08-13 5 views
27

Ceci est une question que j'ai posée sur un autre forum qui a reçu quelques réponses décentes, mais je voulais voir si quelqu'un ici a plus de perspicacité. Le problème est que l'une de vos pages dans une application Web arrive à expiration lorsqu'il arrive à un appel de procédure stockée. Vous devez donc utiliser Sql Profiler ou vos journaux de trace d'application pour rechercher la requête et la coller dans studio de gestion pour comprendre pourquoi il fonctionne lentement. Mais vous l'exécutez à partir de là et ça ne fait que flamber, revenant en moins d'une seconde à chaque fois.La requête expire à partir de l'application Web, mais fonctionne bien à partir du studio de gestion

Mon cas particulier était en utilisant ASP.NET 2.0 et Sql Server 2005, mais je pense que le problème pourrait s'appliquer à n'importe quel système SGBDR.

+0

J'ai eu le même problème et http://stackoverflow.com/questions/250713/sqldataadapter-fill-method-slow résolu mon problème – David

Répondre

26

C'est ce que je l'ai appris si loin de mes recherches.

.NET envoie dans les paramètres de connexion qui ne sont pas les mêmes que ce que vous obtenez lorsque vous vous connectez au studio de gestion. Voici ce que vous voyez si vous renifler la connexion avec Sql Profiler:

-- network protocol: TCP/IP 
set quoted_identifier off 
set arithabort off 
set numeric_roundabort off 
set ansi_warnings on 
set ansi_padding on 
set ansi_nulls off 
set concat_null_yields_null on 
set cursor_close_on_commit off 
set implicit_transactions off 
set language us_english 
set dateformat mdy 
set datefirst 7 
set transaction isolation level read committed 

Je suis coller maintenant les mettre en dessus toutes les requêtes que je lance lorsque vous êtes connecté au serveur SQL, pour vous assurer que les paramètres sont les mêmes. Dans ce cas, j'ai essayé chaque paramètre individuellement, après la déconnexion et la reconnexion, et j'ai constaté que le changement de l'état d'arrêt à activé réduisait le problème de 90 secondes à 1 seconde.

L'explication la plus probable est liée au reniflage de paramètres, une technique que Sql Server utilise pour choisir ce qu'il pense être le plan de requête le plus efficace. Lorsque vous modifiez l'un des paramètres de connexion, l'optimiseur de requête peut choisir un plan différent, et dans ce cas, il a apparemment choisi un mauvais.

Mais je ne suis pas totalement convaincu de cela. J'ai essayé de comparer les plans de requête réels après avoir changé ce paramètre et je n'ai pas encore vu le diff montrer les changements.

Y a-t-il quelque chose d'autre à propos du paramètre arithabort qui pourrait entraîner une exécution lente de la requête dans certains cas? La solution semblait simple: il suffit de mettre set arithabort en haut de la procédure stockée. Mais cela pourrait conduire au problème inverse: changer les paramètres de la requête et tout d'un coup il fonctionne plus vite avec 'off' que 'on'.

Pour le moment, j'utilise la procédure 'with recompile' pour m'assurer que le plan est régénéré à chaque fois. C'est correct pour ce rapport particulier, car il faut peut-être une seconde à recompiler, et ce n'est pas trop visible sur un rapport qui prend 1-10 secondes pour revenir (c'est un monstre).

Mais ce n'est pas une option pour d'autres requêtes qui s'exécutent beaucoup plus fréquemment et doivent retourner aussi rapidement que possible, en quelques millisecondes seulement.

+1

+1 Saisir ces paramètres à partir de SQL Profiler et les coller dans Management Studio est un bon conseil et m'a aidé à charger. –

+3

+ 1 SET ARITHABORT OFF a été suffisant pour que ma requête précédente commence à fonctionner correctement. – Spud

+1

@ eric-z-beard Où mets-tu ces valeurs? Dans le SP ou avant EXEC sp_whatever de .NET – djandreski

0

Essayez de changer la valeur du délai SelectCommand:

DataAdapter.SelectCommand.CommandTimeout = 120; 
+0

Ce n'est pas une solution! C'est une solution de contournement! – Icet

1

Faites le test sur une boîte de mise en scène d'abord, changer au niveau du serveur pour le serveur SQL

@option int déclare

set @option = @@ Options | 64

exec sp_configure 'options utilisateur', @option

reconfigure

2

Avez-vous mis ASP.NET? Traçage encore J'ai eu une instance où ce n'était pas la procédure stockée SQL elle-même qui était le problème, c'était le fait que la procédure renvoyait 5000 lignes et l'application essayait de créer ListItems avec les 5000 éléments qui causaient le problème.

Vous pouvez également examiner les temps d'exécution entre les fonctions de l'application Web via la fonction de trace pour vous aider à effectuer le suivi.

0

Vous pouvez essayer d'utiliser la commande sp_who2 pour voir le processus en question. Cela vous montrera si elle est bloquée par un autre processus, ou si vous utilisez trop de CPU et/ou de temps.

1

Même problème avec les services de génération de rapports SQL. Essayez de vérifier le type de variables, J'envoyais un type différent de variable à SQL comme l'envoi de varchar en place où il devrait être être entier, ou quelque chose comme ça. Après avoir synchronisé les types de variables dans Reporting Service et dans la procédure stockée sur SQL, j'ai résolu le problème.

6

J'ai eu des problèmes similaires. Essayez de définir l'option "WITH RECOMPILE" sur le sproc create pour forcer le système à recalculer le plan d'exécution chaque fois qu'il est appelé. Parfois, le processeur de requête est confus dans les procédures stockées complexes avec beaucoup de branchements ou d'instructions de cas et tire juste un plan d'exécution vraiment sous-optimal. Si cela semble "réparer" le problème, vous devrez probablement vérifier que les statistiques sont à jour et/ou décomposer le sproc.

Vous pouvez également confirmer cela en profilant le sproc. Lorsque vous l'exécutez à partir de SQL Managment Studio, comment se compare l'IO à lorsque vous le profilez à partir de l'application ASP.NET. Si elles sont très nombreuses, cela ne fait que renforcer son plan d'exécution.

0

Nous avons eu le même problème et voici ce que nous avons découvert.

la taille de notre journal de base de données a été maintenue à la valeur par défaut (814 Mo) et la croissance automatique a été de 10%. Sur le serveur, la mémoire maximale du serveur a également été conservée avec le paramètre par défaut (2147483647 Mo). Lorsque notre journal est plein et qu'il a dû grandir, il a utilisé toute la mémoire du serveur et il ne reste plus rien à exécuter pour que le code expire. Ce que nous avons fini par faire était de définir la taille initiale du fichier journal de base de données à 1 Mo et la mémoire maximale du serveur à 2048 Mo. Cela a instantanément résolu notre problème. Bien sûr, vous pouvez modifier ces deux propriétés pour répondre à vos besoins, mais c'est une idée pour quelqu'un qui court dans le problème de temporisation lors de l'exécution d'une procédure stockée via le code, mais cela fonctionne très rapidement dans SSMS.

Questions connexes