6

J'ai une requête qui a des index appropriés et est affichée dans le plan de requête avec un coût de sous-arbre estimé à environ 1,5. Le plan affiche un Index Seek, suivi de Key Lookup - ce qui est bien pour une requête qui devrait renvoyer une ligne d'un ensemble de 5 à 20 lignes (ie l'Index Seek devrait trouver entre 5 et 20 lignes, et après 5 - 20 Key Lookups, nous devrions retourner 1 ligne).Les lectures de base de données varient considérablement sur une requête avec des index

Lorsqu'elle est exécutée de manière interactive, la requête retourne presque immédiatement. Cependant, DB retrace ce matin des runtimes de live (une application web) qui varient énormément; généralement la requête prend < 100 lectures de DB, et effectivement 0 exécution ... mais nous obtenons quelques exécutions qui consomment> 170 000 lectures de DB, et l'exécution jusqu'à 60s (plus grand que notre valeur de délai d'attente).

Qu'est-ce qui pourrait expliquer cette variation dans les lectures de disque? J'ai essayé de comparer interactivement les requêtes et d'utiliser les plans d'exécution réelle de deux exécutions parallèles avec des valeurs de filtre tirées des exécutions rapides et lentes, mais de manière interactive, elles ne montrent effectivement aucune différence dans le plan utilisé. J'ai également essayé d'identifier d'autres requêtes qui pourraient verrouiller celui-ci, mais je ne suis pas sûr que cela aurait un impact sur les lectures de base de données ... et dans tous les cas, cette requête a tendance à être pire pour mon runtime journaux.

Mise à jour: Voici un échantillon du plan produit lorsque la requête est exécutée de manière interactive:

alt text

S'il vous plaît ignorer le texte 'index manquant'. Il est vrai que les modifications apportées aux index actuels pourraient permettre une requête plus rapide avec moins de recherches, mais ce n'est pas le problème ici (il existe déjà des index appropriés). Ceci est un Plan d'exécution réel, où nous voyons des chiffres comme le nombre réel de lignes. Par exemple, sur la recherche d'index, le nombre réel de lignes est de 16 et le coût d'E/S est de 0,003. Le coût d'E/S est le même sur la recherche de clé.

Mise à jour 2: Les résultats de la trace pour cette requête sont:

exec sp_executesql N'select [...column list removed...] from ApplicationStatus where ApplicationGUID = @ApplicationGUID and ApplicationStatusCode = @ApplicationStatusCode;',N'@ApplicationGUID uniqueidentifier,@ApplicationStatusCode bigint',@ApplicationGUID='ECEC33BC-3984-4DA4-A445-C43639BF7853',@ApplicationStatusCode=10 

La requête est construit en utilisant la classe Gentle.Framework SQLBuilder, qui construit des requêtes paramétrées comme ceci:

SqlBuilder sb = new SqlBuilder(StatementType.Select, typeof(ApplicationStatus)); 
sb.AddConstraint(Operator.Equals, "ApplicationGUID", guid); 
sb.AddConstraint(Operator.Equals, "ApplicationStatusCode", 10); 
SqlStatement stmt = sb.GetStatement(true); 
IList apps = ObjectFactory.GetCollection(typeof(ApplicationStatus), stmt.Execute()); 

Répondre

1

Les données peuvent-elles être supprimées du cache? Cela peut être une explication pourquoi avec un cache chaud (données déjà en mémoire), les lectures enregistrées sont très faibles .... et puis quand les données ne sont plus en RAM, les lectures augmenteraient car il doit le lire du disque encore.

Juste une idée pour faire bouger les choses.

+0

Je ne pense pas; Ma compréhension était que profilage montrerait les lectures de disque logique même si elles ont été récupérées à partir du cache. Pas quelque chose dont je suis certain, cependant. – Nij

1

Exécutez le profileur pour voir si les statistiques sont mises à jour en même temps. Ou simplement pour voir ce qui se passe d'autre.

Ajoutez également la requête SQL ainsi que le code client.

Pensées:

  • On dirait que vos « lignes » pourrait 5-20 être beaucoup plus que cela
  • Avec un mauvais plan/paramètre renifler obtiendrez toujours mauvaise performance
  • Comment peut écrit se produire sur cette table: assez pour mettre à jour les statistiques?
  • Y a-t-il un problème de type de données? (par exemple concaténation de paramètres et introduction d'une conversion de type de données)
+0

@gbn: Les statistiques sur les index impliqués ont été mises à jour il y a environ 3 jours pour autant que je puisse voir (nous avons un travail qui le force). J'ai ajouté une capture d'écran du plan de requête (lorsqu'il est exécuté de manière interactive). Je ne crois pas qu'il y ait un problème de type de données. C'est une table qui a des enregistrements ajoutés fréquemment (sur un PK d'identité) ... Je devrai faire des recherches dans quelles circonstances cela pourrait forcer des statistiques de mise à jour et si cela montrerait sous les lectures d'une requête. – Nij

+0

@Nij: Le plan est évidemment OK (bien, pourrait être couvert) et n'aide pas ici ... c'est le code SQL et le code client qui serait utile. – gbn

+0

@gbn: La requête est affichée sur la capture d'écran ci-dessus près du sommet. Je ne suis pas à 100% sur ce que vous voulez dire quand vous dites le code client, mais si vous voulez dire quelque chose comme le code source C#, je ne suis pas sûr de savoir comment cela aurait un impact sur les lectures de DB. – Nij