2009-03-19 11 views
6

J'ai exécuter la requête 2 secondes à ~ MSSMS (retour 25K de lignes)Ralentissement des performances de SqlDataReader

requête même utilisé dans .NET (sqlReader) exetuting quelques minutes!

J'ai aussi essayé d'exécuter lecteur ne

(commenté dans tout le code en boucle tout en laissant reader.Read()) - toujours même!

Toute idée de ce qui se passe?

+0

Pouvez-vous poster du code? –

+0

Est-ce que le profileur de requête Sql révèle des indications sur le problème? –

+0

EJB: le code n'est pas à publier. Le problème est le même même si nous utilisons la commande pure Execute reader (disponible dans MS help) – Maciej

Répondre

2

Je ne suis pas DBA et non PRIVILÉGIÉ jouer avec Profiler - demandera mon DBA et que tous savent.

En attendant, je suis remarqué gain de performance essentiel après avoir ajouté « AVEC RECOMPILE » à SP param Je parle

Donc, de mon point de vue, il semble être le cas avec le plan d'exécution ... Que pensez-vous?

[EDIT] aussi ce que j'ai vérifié exécutait ci-dessous requête de QA et .NET

select @@options 

Ma compréhension est elle renvoie même valeur pour les deux environements. (Si non differnet ex.plans sera utilisé) Ai-je raison?

[EDIT2] J'ai lu (de http://www.sqldev.net/misc/fn_setopts.htm) qui ARITHABOIRT = ON dans QA (en .NET, il est désactivé)

Est-ce enybody savoir comment forcer ARITHABOIRT = ON pour chaque. Connexions NET?

+3

@Maciej - Vous pouvez activer ARITHABORT ON en exécutant une commande avec ce texte en utilisant votre objet Connection avant d'appeler ExecuteReader. L'option set sera en vigueur pour la durée de cette connexion. –

+0

La même chose m'est arrivée. SP aveuglant rapidement, l'appel de .NET prenait une éternité. J'ai ajouté SET ARITHABORT = ON et tout s'est magiquement accéléré ... – abx78

0

Je vérifier combien de temps la récupération réelle prend.

par exemple:

Private Sub timeCheck() 
    'NOTE: Assuming you have a sqlconnection object named conn 

    'Create stopwatch 
    Dim sw As New System.Diagnostics.Stopwatch 

    'Setup query 
    Dim com As New SqlClient.SqlCommand("QUERY GOES HERE", conn) 

    sw.Start() 

    'Run query 
    Dim dr As SqlClient.SqlDataReader = com.ExecuteReader() 

    sw.Stop() 

    'Check the time 
    Dim sql_query_time As String = CStr((sw.ElapsedMilliseconds/1000)) & " seconds" 
    End Sub 

Cela vous permettra de voir si le hold-up est dans la recherche ou dans l'exécution du lecteur.

0

Si vous ar exécuter le lecteur dans une boucle, où il exécute plusieurs fois, alors assurez-vous que vous utilisez CommandBehavior.CloseConnection

SqlCommand cmd = new SqlCommand(); 
    SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection) 

Si vous n'êtes pas, chaque fois que la boucle exécutera la ligne, quand il se termine et que le rdr et l'objet de connexion tombent hors de portée, l'objet connexion ne sera pas explicitement fermé, donc il ne sera fermé et relâché dans le pool que lorsque le garbage collector finira par le finaliser ...

Ensuite, si votre boucle est assez rapide, (ce qui est très probable), vous serez à court de connexions. (Le pool a une limite maximum qu'il peut générer)

Cela entraînera une latence et des retards supplémentaires car le code continue de créer des connexions supplémentaires inutiles (jusqu'au maximum) et attend que le GC "rattrape" la boucle qui les utilise ...

+0

La question initiale mentionne seulement l'exécution d'une requête qui prend beaucoup de temps, il n'y a rien à propos de la création de beaucoup d'objets SqlConnection et l'exécution de beaucoup de requêtes. – sisve

+5

mec, la requête originale mentionne une boucle ... quoi de neuf avec les gens sur ce site de toute façon? ce n'est pas votre fonction d'identifier chaque nit mineur dans les réponses des autres peuples. Sauf si quelqu'un dit quelque chose de mal, gardez vos commentaires sur une note positive s'il vous plaît. –

+0

Je pense que Simon veut dire que ce serait bien si la réponse suggérée avait quelque chose à voir avec la question originale. Il a raison, la question d'origine n'a rien à voir avec les connexions, elle concerne le code exécuté dans une boucle .Read(), ce qui signifie qu'il n'y a qu'une seule connexion. Donc, techniquement, vous avez dit quelque chose de faux, en ce sens que vous avez répondu à une question qui n'a pas été posée. –

4

Je voudrais configurer une trace dans SQL Server Profiler pour voir quels paramètres d'options SET la connexion utilise lors de la connexion à partir du code .NET, et quels paramètres sont utilisés dans SSMS. Par paramètres d'options SET, je veux dire

ARITHABORT 
ANSI_NULLS 
CONCAT_NULL_YIELDS_NULL 
//etc 

Jetez un oeil à MSDN pour une table d'options

J'ai vu le problème avant où les options étaient différentes (dans ce cas, ARITHABORT) et la différence de performance était énorme.

0

En outre, l'analyseur de requête ne télécharge pas le contenu complet du grand texte ou de grands champs binaires. Votre SqlDataReader peut prendre plus de temps car il télécharge le contenu complet.

3

J'ai eu ce problème à. Cochez le paramètre "abandon arithmétique" dans les paramètres de connexion du serveur de base de données.

+0

Dans votre cas, vous avez aidé à cocher ou à décocher cette option? – Maciej

+0

Vous souhaitez l'activer comme suit, 'MyCommand.CommnadText =" SET ARITHABORT ON; "+ MyCommand.CommnadText;' – JasonRShaver

Questions connexes