Partage via


Optimiser les performances à l’aide de FetchXml

Cet article décrit les façons dont vous pouvez optimiser les performances lors de la récupération de données à l’aide de FetchXml.

Modèles à éviter

La composition de requêtes optimisées pour Dataverse est essentielle pour garantir que les applications offrent une expérience rapide, réactive et fiable. Cette section décrit les modèles à éviter et les concepts à comprendre lors de la composition de requêtes pour des tables standard à l’aide du RetrieveMultiple message ou de messages dont le paramètre hérite de la classe QueryBase. Ces conseils s’appliquent également lors de l’envoi d’une requête sur une collection d’enregistrements à l’aide d’OData. GET Les conseils présentés ici peuvent ne pas s’appliquer aux tableaux Elastic ou lors de l’utilisation de Dataverse recherche.

Minimiser le nombre de colonnes sélectionnées

N’incluez pas les colonnes dont vous n’avez pas besoin dans votre requête. Les requêtes qui renvoient toutes les colonnes ou incluent un grand nombre de colonnes peuvent rencontrer des problèmes de performances en raison de la taille du jeu de données ou de la complexité de la requête.

Cette pratique est particulièrement vraie pour les colonnes logiques. Une colonne logique contient des valeurs stockées dans différentes tables de base de données. La propriété AttributeMetadata.IsLogical vous indique si une colonne est une colonne logique. Les requêtes qui contiennent de nombreuses colonnes logiques sont plus lentes car Dataverse doivent combiner les données d’autres tables de base de données.

Évitez les caractères génériques en tête dans les conditions de filtrage

Les requêtes qui utilisent des conditions avec des caractères génériques de début (soit explicitement, soit implicitement avec un opérateur tel que ends-with) peuvent entraîner de mauvaises performances. Dataverse ne peut pas profiter des index de base de données lors d’une requête utilisant des caractères génériques de premier plan, ce qui oblige SQL à analyser la table entière. Les analyses de table peuvent avoir lieu même s’il existe d’autres requêtes génériques non principales qui limitent l’ensemble de résultats.

L’exemple suivant est un élément de condition FetchXml qui utilise un caractère générique de début :

<condition attribute='accountnumber'
   operator='like'
   value='%234' />

L’exemple suivant est un QueryExpression ConditionExpression qui utilise un caractère générique de début :

new ConditionExpression("accountnumber", ConditionOperator.Like, "%234")

L’exemple suivant est une requête OData qui utilise un caractère générique de début carte :

$filter=startswith(accountnumber,'%234')

Lorsque le délai d’attente des requêtes expire et que ce modèle est détecté, Dataverse renvoie une erreur unique pour aider à identifier les requêtes qui utilisent ce modèle :

Nom: LeadingWildcardCauseTimeout
Code : 0x80048573
Nombre : -2147187341
Message : The database operation timed out; this may be due to a leading wildcard value being used in a filter condition. Please consider removing filter conditions on leading wildcard values, as these filter conditions are expensive and may cause timeouts.

Dataverse limite fortement les principales requêtes génériques identifiées comme un risque pour la santé de l’organisation afin d’aider à prévenir les pannes. En savoir plus sur les limitation de requêtes

Si vous utilisez des requêtes génériques de premier plan, étudiez ces options :

  • Utiliser Dataverse la recherche à la place.
  • Modifiez votre modèle de données pour aider les gens à éviter d’avoir besoin de caractères génériques de premier plan.

En savoir plus sur l’utilisation de caractères génériques dans les conditions pour les valeurs de chaîne

Évitez d’utiliser des formules ou des colonnes calculées dans des conditions de filtre

Les valeurs des formules et colonnes calculées en temps réel quand elles sont récupérées. Les requêtes qui utilisent des filtres sur ces colonnes obligent Dataverse à calculer la valeur de chaque enregistrement possible pouvant être renvoyé afin que le filtre puisse être appliqué. Les requêtes sont plus lentes car Dataverse ne peut pas améliorer les performances de ces requêtes à l’aide de SQL.

Lorsque le délai d’attente des requêtes expire et que ce modèle est détecté, Dataverse renvoie une erreur unique pour aider à identifier les requêtes qui utilisent ce modèle :

Nom: ComputedColumnCauseTimeout
Code : 0x80048574
Nombre : -2147187340
Message : The database operation timed out; this may be due to a computed column being used in a filter condition. Please consider removing filter conditions on computed columns, as these filter conditions are expensive and may cause timeouts.

Pour éviter les pannes, Dataverse applique des limitations aux requêtes comportant des filtres sur les colonnes calculées identifiées comme présentant un risque pour la santé de l’environnement. En savoir plus sur les limitation de requêtes

Évitez de trier par colonnes de choix

Lorsque vous utilisez FetchXml ou QueryExpression, lorsque vous triez les résultats de la requête à l’aide d’une colonne de choix, les résultats sont triés à l’aide de l’étiquette localisée pour chaque option de choix. Trier par la valeur numérique stockée dans la base de données ne fournirait pas une bonne expérience dans votre application. Vous devez savoir que le classement des colonnes de choix nécessite davantage de ressources de calcul pour joindre et trier les lignes en fonction de la valeur d’étiquette localisée. Ce travail supplémentaire ralentit la requête. Si possible, essayez d’éviter de trier les résultats par valeurs de colonne de choix.

Notes

OData est différent. Avec l’ Dataverse API Web, $orderby trie les lignes à l’aide de la valeur entière de la colonne de choix plutôt que de l’étiquette localisée.

Le classement par colonnes sur les tables associées ralentit la requête en raison de la complexité supplémentaire.

Le classement par tables associées ne doit être effectué qu’en cas de besoin, comme décrit ici :

Évitez d’utiliser des conditions sur de grandes colonnes de texte

Dataverse dispose de deux types de colonnes pouvant stocker de grandes chaînes de texte :

La limite pour ces deux colonnes est spécifiée à l’aide de la propriété MaxLength .

Vous pouvez utiliser des conditions sur les colonnes de chaîne dont a MaxLength est configuré pour moins de 850 caractères.

Toutes les colonnes mémo ou colonnes de chaîne avec un MaxLength supérieur à 850 sont définies dans Dataverse en tant que grandes colonnes de texte. Les grandes colonnes de texte sont trop volumineuses pour être indexées efficacement, ce qui entraîne de mauvaises performances lorsqu’elles sont incluses dans une condition de filtre.

Dataverse La recherche est un meilleur choix pour interroger des données dans ce type de colonnes.

Requête de matérialisation tardive

Si vous sélectionnez de nombreuses colonnes de recherche et calculées et que vous rencontrez des problèmes de performances, vous pouvez essayer de définir l’attribut latematerialize de l’élément fetch. En arrière-plan, ce paramètre divise la requête en parties plus petites et réassemble les résultats avant de vous les renvoyer.

L’utilisation de l’attribut latematerialize peut ne pas toujours offrir un avantage en termes de performances. Il peut ralentir l’exécution de requêtes simples. Il est plus bénéfique lorsque votre requête :

  • Dispose de nombreuses jointures
  • Contient de nombreuses colonnes de recherche ou calculées

Indicateurs de requête

Important

Appliquez ces options uniquement lorsqu’elles sont recommandées par le support technique Microsoft. Une utilisation incorrecte de ces options peut dégrader les performances d’une requête.

Microsoft SQL Server prend en charge plusieurs indicateurs de requête pour optimiser les requêtes. FetchXML prend en charge les indicateurs de requête et peut transmettre ces options de requête à SQL Server avec élément extraire options attribut.

Option de requête Conseil SQL Server
ForceOrder Forcer l’ordre
DisableRowGoal Conseil : DISABLE_OPTIMIZER_ROWGOAL
EnableOptimizerHotfixes Conseil : ENABLE_QUERY_OPTIMIZER_HOTFIXES
LoopJoin Mettre en boucle la jonction
MergeJoin Fusionner la jonction
HashJoin Hacher la jonction
NO_PERFORMANCE_SPOOL NO_PERFORMANCE_SPOOL
ENABLE_HIST_AMENDMENT_FOR_ASC_KEYS Conseil : ENABLE_HIST_AMENDMENT_FOR_ASC_KEYS

Plus d’information : Conseils (Transact-SQL) - Requête

Aucun verrou

Dans les versions antérieures, l’attribut no-lock était utilisé pour empêcher les verrous partagés dans les enregistrements. Il n’est plus nécessaire d’inclure cet attribut.

Indicateur d’union

Vous pouvez améliorer les performances lors de l’ajout d’un élément filter qui définit la condition pour les colonnes de différentes tables en définissant l’attribut hint sur union. Mais certaines restrictions s’appliquent :

  • Le filtre doit utiliser le type de filtre or.
  • Chaque requête ne peut contenir qu’un seul indicateur union.
  • Si un filtre avec un indicateur union n’est pas un filtre de niveau supérieur, Dataverse transforme la requête et déplace le filtre avec un indicateur union vers le filtre racine.
  • Si un indicateur union dispose de plus de trois niveaux de profondeur, il est ignoré.

L’exemple suivant définit un filtre avec l’indicateur union sur la colonne telephone1 à la fois pour les tables compte et contact.

<fetch>
   <entity name="email">
      <attribute name="activityid" />
      <attribute name="subject" />
      <filter type="and">
         <condition attribute="subject"
            operator="like"
            value="Alert:%" />
         <condition attribute="statecode"
            operator="eq"
            value="0" />
         <filter type="or"
            hint="union">
            <condition attribute="telephone1"
               operator="eq"
               value="555-123-4567"
               entityname="ac" />
            <condition attribute="telephone1"
               operator="eq"
               value="555-123-4567"
               entityname="co" />
         </filter>
      </filter>
      <link-entity name="account"
         from="accountid"
         to="regardingobjectid"
         link-type="outer"
         alias="ac" />
      <link-entity name="contact"
         from="contactid"
         to="regardingobjectid"
         link-type="outer"
         alias="co" />
   </entity>
</fetch>

Voir aussi

Interroger des données à l’aide de FetchXml
Récupérer des données à l’aide de FetchXml
Sélectionner des colonnes à l’aide de FetchXml
Joindre des tables à l’aide de FetchXml
Trier des lignes à l’aide de FetchXml
Filtrer des lignes à l’aide de FetchXml
Paginer des résultats à l’aide de FetchXml
Agréger des données à l’aide de FetchXml
Compter des lignes à l’aide de FetchXml
Référence FetchXml
Exemple de code FetchXml

Notes

Pouvez-vous nous indiquer vos préférences de langue pour la documentation ? Répondez à un court questionnaire. (veuillez noter que ce questionnaire est en anglais)

Le questionnaire vous prendra environ sept minutes. Aucune donnée personnelle n’est collectée (déclaration de confidentialité).