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:
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());
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