2010-12-01 6 views
5

Je rencontre un problème lors du remplissage d'un jeu d'enregistrements ADO dans VB6. La requête (SQLServer 2008) ne prend que 1 seconde à courir quand je l'utilise avec SSMS. Cela fonctionne bien lorsque le jeu de résultats est petit, mais quand il s'agit de quelques centaines d'enregistrements, cela prend beaucoup de temps. Plus de 800 enregistrements nécessitent environ 5 minutes pour retourner (la requête ne prend que 1 seconde dans le SSMS), et 6000+ prend bien plus de 20 minutes. J'ai "fixé" l'exception en augmentant le délai d'expiration de la commande, mais je me demandais s'il y avait un moyen de le faire fonctionner plus vite car il ne semble pas que la requête réelle demande autant de temps. Quelque chose comme la compression des résultats, cela ne prend pas autant de temps. Le jeu d'enregistrements est ouvert comme suit:Résolution d'un problème de délai d'attente ADO dans VB6

myConnection.CommandTimeout = 2000 
myConnection.ConnectionString = "Provider=SQLOLEDB;" & _ 
     "Initial Catalog=DB_NAME;" & _ 
     "Data Source=SERVER_NAME" & _ 
     "Network Library=DBMSSOCN;" & _ 
     "User ID=USER_NAME;" & _ 
     "Password=PASSWORD;" & _ 
     "Use Encryption for Data=True;" 
myConnection.Open 

myRecordSet.Open STORED_PROC_QUERY_STRING, myConnection, adOpenStatic, adLockReadOnly 
Set myRecordSet.ActiveConnection = Nothing 

myConnection.Close 

Les données retournent 3 colonnes utilisées pour remplir une zone de liste modifiable. J'ai exécuté SQL Profiler, et les instances de l'ordinateur client effectuent plus de lectures et prennent plus de temps d'un facteur 100 que les deux métriques pour les requêtes dans SSMS. Le texte de la requête est le même pour SSMS et la machine client selon le profileur, donc je ne pense pas qu'il devrait utiliser un plan d'exécution différent. Est-ce que la bibliothèque réseau ou le fournisseur peut avoir un impact sur cela?

Statistiques Profiler:

  • De l'application cliente: 7041720 lectures, 59458 ms, 3900 ligne compte
  • De SSMS: 30802 lectures, 238 ms durée, 3900 rangée compte

Il semble qu'il utilise un plan d'exécution différent, mais la requête est exactement la même et je ne suis pas sûr de savoir comment vérifier le plan d'exécution que le client pourrait utiliser s'il est différent om ce qui est montré dans SSMS.

+0

Avez-vous essayé de supprimer le "Utiliser le cryptage pour les données"? – Andomar

+0

Non, mais ce n'est pas vraiment une option disponible. Ceci est une application client. –

+1

Avez-vous essayé de profiler les appels et [en regardant les plans d'exécution] (http://stackoverflow.com/questions/3831644/why-does-a-database-query-only-go-slow-in-the-application/ 3831685 # 3831685) pour vérifier que ce n'est certainement pas un problème de reniflage des paramètres? –

Répondre

3

800+ records requires about 5 minutes = problème de requête.

oeil à votre plan d'exécution:

En SSMS, exécutez:

SET SHOWPLAN_ALL ON

puis exécutez votre requête, il ne produira pas le jeu de résultat attendu, mais un plan de exceution sur la façon dont la base de données récupère vos données. La plupart des mauvaises requêtes effectuent généralement une analyse de table (regardez chaque ligne de la table, ce qui est lent), alors recherchez le mot "SCAN" dans la colonne StmtText. Essayez de comprendre pourquoi l'index n'est pas utilisé sur cette table (le nom sera là par le mot "SCAN"). Si vous vous joignez à plusieurs tables et que plusieurs SCAN se concentrent sur les plus grandes tables en premier.

Sans plus d'informations c'est la meilleure aide "générique" que vous pouvez obtenir.

EDIT
À la lecture de votre question, je ne sais pas si vous voulez dire qu'il est toujours rapide de SSMS, peu importe les lignes, mais lent à partir de VB que les lignes augmentent.Si tel est le cas, vérifier ceci: http://www.google.com/search?q=sql+server+fast+from+ssms+slow+from+application&hl=en&num=100&lr=&ft=i&cr=&safe=images

pourrait être quelque chose comme: renifler ou les paramètres de connexion incompatibles (nulls ANSI, arithabort, etc.)

pour les paramètres de connexion, essayez d'exécuter ces de SSMS et de VB6 (les ajouter à l'ensemble de résultats) et voir s'il y a des différences:

SELECT SESSIONPROPERTY ('ANSI_NULLS') --Specifies whether the SQL-92 compliant behavior of equals (=) and not equal to (<>) against null values is applied. 
             --1 = ON 
             --0 = OFF 

SELECT SESSIONPROPERTY ('ANSI_PADDING') --Controls the way the column stores values shorter than the defined size of the column, and the way the column stores values that have trailing blanks in character and binary data. 
             --1 = ON 
             --0 = OFF 

SELECT SESSIONPROPERTY ('ANSI_WARNINGS') --Specifies whether the SQL-92 standard behavior of raising error messages or warnings for certain conditions, including divide-by-zero and arithmetic overflow, is applied. 
             --1 = ON 
             --0 = OFF 

SELECT SESSIONPROPERTY ('ARITHABORT') -- Determines whether a query is ended when an overflow or a divide-by-zero error occurs during query execution. 
             --1 = ON 
             --0 = OFF 

SELECT SESSIONPROPERTY ('CONCAT_NULL_YIELDS_NULL') --Controls whether concatenation results are treated as null or empty string values. 
                --1 = ON 
                --0 = OFF 

SELECT SESSIONPROPERTY ('NUMERIC_ROUNDABORT') --Specifies whether error messages and warnings are generated when rounding in an expression causes a loss of precision. 
               --1 = ON 
               --0 = OFF 

SELECT SESSIONPROPERTY ('QUOTED_IDENTIFIER') --Specifies whether SQL-92 rules about how to use quotation marks to delimit identifiers and literal strings are to be followed. 
              --1 = ON 
              --0 = OFF 

faire votre requête comme (vous pouvez donc voir les paramètres de connexion à VB6):

SELECT 
    col1, col2 
     ,SESSIONPROPERTY ('ARITHABORT') AS ARITHABORT 
     ,SESSIONPROPERTY ('ANSI_WARNINGS') AS ANSI_WARNINGS 
    FROM ... 
+0

Par la publication d'origine, la requête s'exécute en moins d'une seconde dans SSMS. Le texte de la requête est exactement le même (confirmé avec SQL Profiler). J'ai regardé le plan d'exécution, et ça a l'air bien. Tous les index sont utilisés. –

+0

Il est vraiment utile de comparer les propriétés de la session ci-dessus car elles peuvent affecter les performances, à tout le moins essayer la requête ADO après l'émission d'un SET ARITHABORT ON –

+0

C'était la propriété arithabort. Merci pour l'aide. –