Sensibilité à la casse lors de l'interrogation de SQL Server 2005 à partir de .NET à l'aide d'OleDB

StackOverflow https://stackoverflow.com/questions/150017

Question

J'ai une requête que j'exécute depuis une application .NET vers une base de données SQL Server et cela semble prendre un certain temps (5 minutes et plus). J'ai créé une application de test en c # pour essayer de voir ce qui se parlait si longtemps (la requête devrait revenir rapidement).

Alors que je reconstruisais la requête en ajoutant des éléments pour voir quelle partie prenait si longtemps, j'ai fini par reconstruire la requête pratiquement mot pour mot, la seule différence étant les espaces de la requête d'origine et une différence de capitalisation. Cette différence a généré un résultat en environ 100 millisecondes.

Quelqu'un a-t-il déjà vu cela? Je me demande s'il existe des services désactivés sur notre serveur (puisqu'un collègue a le même problème) ou sur nos ordinateurs.

Merci d'avance pour votre aide.

Exemple de code ci-dessous (différence dans la première ligne de la requête à la fin (fk_source vs fk _source):

//Original
    OleDbCommand comm = new OleDbCommand("select min(ctc.serial_no) as MIN_INTERVAL from countstypecode ctc, source s, countstype ct, counts c where ct.value_id=c.value_id and s.c_id=ct.fk_source and " +
      "ct.timeinterval=ctc.typename and ct.timeinterval in ('15min','1h','1day') and c.time_stamp >=  CONVERT(datetime,'01-01-2008',105)  and c.time_stamp < " +
      "CONVERT(datetime,'01-01-2009',105)  and s.c_id = '27038dbb19ed93db011a315297df3b7a'", dbConn);

//Rebuilt
    OleDbCommand comm = new OleDbCommand("select min(ctc.serial_no) as MIN_INTERVAL from countstypecode ctc, source s, countstype ct, counts c where ct.value_id=c.value_id and s.c_id=ct.fk_Source and " +
      "ct.timeinterval=ctc.typename and ct.timeinterval in ('15min','1h','1day') and c.time_stamp >= CONVERT(datetime,'01-01-2008',105) and c.time_stamp < " +
      "CONVERT(datetime,'01-01-2009',105) and s.c_id='27038dbb19ed93db011a315297df3b7a'", dbConn);
Était-ce utile?

La solution

Je soupçonne qu'il s'agit d'un problème de cache de procédure. Un des avantages des procédures stockées est que le plan est stocké pour vous, ce qui accélère les choses. Malheureusement, il est possible d’obtenir un mauvais plan dans le cache (même en utilisant des requêtes dynamiques).

Juste pour le plaisir, j’ai vérifié le cache de ma procédure, lancé une requête ad hoc, vérifié une nouvelle fois, puis j’ai exécuté la même requête avec une capitalisation différente et j’ai eu la surprise de voir le nombre de procédures augmenter.

Essayez ceci ....

Connectez-vous à SQL Server Management Studio.

DBCC MemoryStatus

Select Columns... From TABLES.... Where....

dbcc MemoryStatus

Select Columns... From tables.... Where....

dbcc MemoryStatus

Je pense que vous constaterez que TotalProcs change lorsque l’instruction change (même lorsque la seule modification est sensible à la casse).

La mise à jour de vos statistiques peut aider. Il s’agit d’un processus assez lent. Vous voudrez peut-être l’exécuter pendant une période lente.

Autres conseils

Depuis que vous utilisez SQL Server 2005, avez-vous essayé avec un objet SqlCommand au lieu de l'objet OleDbCommand?

Je ne vois aucune différence dans vos requêtes qui affecterait les performances. Qu'en est-il de la mise en cache ou des modifications d'index / statistiques entre les exécutions? Le plan d'exécution peut avoir changé en raison de statistiques ou de modifications d'index.

En ce qui concerne le cas: la casse peut avoir de l'importance si la base de données est sensible à la casse, mais pour que les deux requêtes puissent s'exécuter dans une base de données sensible à la casse, il doit exister des colonnes nommées dans les deux formats - l'analyseur de requête obéira le cas - cela ne causera pas de différence de performance.

Tout d’abord, êtes-vous sûr à 100% que c’est la requête qui ne va pas? Vérifiez le profil de trace dans le serveur SQL pour voir combien de temps il prend dans la base de données.

Deuxièmement, obtenez-vous le même nombre de résultats? La capitalisation ne devrait pas avoir d’importance par défaut sur le serveur SQL, mais elle aurait pu être configurée différemment.

Si j'avais une requête qui prenait "5+ minutes", je ne m'inquiéterais pas des 100 millisecondes qu'il faut pour faire correspondre le cas de la chaîne.

merci pour toutes vos réponses, je vais répondre à chacune à son tour:

1) Russ, je suis d’accord pour dire que SQLConnection serait préférable, mais malheureusement, je n’arrive pas à définir le type de connexion. Je viens de créer une petite application pour tester cette requête, mais celle-ci est créée de manière dynamique dans une application beaucoup plus grande.

2) gbjbaanb, Je pense que ce n'est pas un problème de serveur, car je peux exécuter les deux requêtes à partir du studio de gestion à peu près au même moment. Cela ne semble être un problème que lorsqu'il est exécuté via oledb dans .net (1.1 et 2.0) . Nous avons exécuté un profileur sur celui-ci et le fichier de trace a confirmé qu'il fallait plus de 5 minutes pour compléter la requête lorsque cette méthode est appelée.

3) Joel Coehoorn, Je suis d’accord, mais ce que j’essaie de faire ici est de savoir "pourquoi". parce que pour le moment nous ne savons pas quelle est l'ampleur de ce problème et où il se situe.

4) Cade Roux, la différence est très reproductible, donc je ne pense pas que ce soit un problème de modification d'index ou de mise en cache car j'ai exécuté les tests dos à dos avec les mêmes résultats et qu'ils prennent à peu près le même temps en SQL Server à exécuter.

Merci à G Mastros pour la réponse la plus complète, bien que rétrospectivement, la mise à jour statistique ait été suggérée par Cade. La solution de G Mastos était toutefois mieux adaptée à mon niveau d’expérience SQL Server.

Merci d'aider tout le monde!

Je vais voir pourquoi cette différence apparemment innocente a de si grandes conséquences

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top