Note
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de changer d’annuaire.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de changer d’annuaire.
S’applique à : SQL Server 2025 (17.x)
Azure SQL Database
SQL database in Microsoft Fabric
L’optimisation facultative du plan de paramètres (OPPO) améliore la qualité du plan de requête pour les requêtes qui incluent des paramètres facultatifs. Dans ces requêtes, le plan d’exécution optimal varie selon qu’une valeur de paramètre est NULL au moment de l’exécution. Le terme paramètres facultatifs fait référence à une variante spécifique du problème de plan sensible aux paramètres (PSP), dans laquelle la valeur du paramètre au moment de l’exécution détermine si la requête nécessite une recherche ou une analyse.
Aperçu
Les requêtes qui utilisent des paramètres facultatifs incluent souvent des prédicats qui appliquent des filtres de manière conditionnelle selon qu’une valeur de paramètre est fournie. Un modèle courant est le suivant :
SELECT column1,
column2
FROM Table1
WHERE (column1 = @p
OR @p IS NULL);
Quand @p IS NOT NULL, une recherche d’index sur col1 est souvent le plan d’exécution le plus efficace. Quand @p IS NULL, le prédicat est évalué à TRUE, et une analyse séquentielle peut être plus appropriée. Sans OPPO, le moteur de base de données SQL Server doit compiler et mettre en cache un plan d’exécution unique valide pour les deux cas. Étant donné qu’un plan basé sur la recherche n’est pas valide quand @p IS NULL, l’optimiseur choisit souvent un plan conservateur basé sur l’analyse pour toutes les exécutions. Ce choix peut entraîner des choix de plan inefficaces et une utilisation excessive des ressources pour les exécutions sélectives.
Les techniques d’indication traditionnelles telles que OPTIMIZE FOR ne sont pas efficaces dans ce scénario, car le plan doit rester correct pour les deux états de paramètre.
OPPO utilise l’infrastructure d’optimisation de plan adaptatif (Multiplan) introduite avec l’optimisation du plan sensible aux paramètres (PSP). Cette infrastructure génère et met en cache plusieurs plans d’exécution pour une instruction unique, ce qui permet à OPPO d’effectuer différentes hypothèses en fonction des valeurs de paramètre utilisées dans la requête.
Terminologie et fonctionnement
OPPO s’appuie sur l’infrastructure d’optimisation de plan adaptatif (Multiplan), qui est également utilisée par l’optimisation de plan sensible aux paramètres. À l’aide de Multiplan, le moteur de base de données peut générer et mettre en cache plusieurs plans d’exécution pour une requête unique.
Lorsque le moteur de base de données détecte un modèle de paramètre facultatif éligible, il crée :
- Un plan de gestionnaire de tâches
- Une ou plusieurs variantes de requête, chacune optimisée pour un état de valeur de paramètre spécifique
Au moment de l’exécution :
- Le moteur de base de données évalue la valeur du paramètre.
- Le répartiteur Multiplan sélectionne la variante de requête appropriée.
- La variante de requête sélectionnée s’exécute.
Une fois que le moteur de base de données sélectionne une variante de requête, il simplifie les prédicats en fonction de la valeur de paramètre réelle. Considérez l’expression suivante :
@p1 IS NULL
Dans cet exemple, l’expression est simplifiée en résultat constant pour la variante sélectionnée. Ce repli de résultat constant permet à l’optimiseur de générer des plans d’exécution qui ne sont pas valides dans un plan réutilisable unique.
En sélectionnant des plans de cette façon, OPPO permet une exécution efficace pour différents états de paramètres sans nécessiter de réécritures de requête ou d’indicateurs de requête manuels.
L’optimisation OPPO et PSP traite différentes variantes de problèmes liés aux paramètres dans les plans.
L’optimisation PSP sélectionne des plans en fonction des différences de cardinalité estimées pour les prédicats d’égalité ou de plage.
OPPO sélectionne des plans en fonction de la valeur
NULLd’un paramètre.
Une requête unique peut tirer parti soit des deux fonctionnalités, soit d'une seule, en fonction des prédicats impliqués.
Modèles de requête pris en charge
L’optimisation facultative du plan de paramètres s’applique aux requêtes où NULL les vérifications sur les paramètres affectent la validité du plan d’exécution. Par exemple, considérez un formulaire en ligne d'une application pour une société immobilière qui permet un filtrage facultatif sur le nombre de chambres à coucher pour une annonce particulière. OPPO s’applique aux prédicats de paramètres facultatifs disjonctifs tels que :
SELECT *
FROM Properties
WHERE bedrooms = @bedrooms
OR @bedrooms IS NULL;
Même si les marqueurs de paramètres peuvent sniffer le @bedrooms = 10 paramètre, et que vous savez que la cardinalité pour le nombre de chambres est susceptible d’être très faible, l’optimiseur ne produit pas de plan qui recherche sur un index qui existe sur la colonne de chambre, car ce n’est pas un plan valide pour le cas où @bedrooms est NULL. Le plan généré n’inclut pas d’analyse de l’index.
Imaginez si vous pouvez réécrire cette requête sous la forme de deux instructions distinctes. Selon la valeur d’exécution du paramètre, vous pouvez évaluer l’exemple suivant :
IF @bedrooms IS NULL
SELECT *
FROM Properties;
ELSE
SELECT *
FROM Properties
WHERE bedrooms = @bedrooms;
La fonctionnalité peut y parvenir à l’aide de l’infrastructure Multiplan, qui permet la création d’un plan de répartiteur qui répartit une variante de requête.
OPPO incorpore un indicateur de requête généré par le système PLAN PER VALUE (optional_predicate) dans les métadonnées du plan pour associer chaque variante de requête à son état des paramètres. Cet indicateur est généré par le système et incorporé dans le texte de requête du plan. Cet indicateur n’est pas valide pour une utilisation par une application ou pour être appliqué manuellement.
En continuant avec l’exemple précédent,
SELECT *
FROM Properties
WHERE bedrooms = @bedrooms
OR @bedrooms IS NULL;
OPPO peut générer deux variantes de requête qui peuvent avoir les attributs suivants ajoutés dans le code XML showplan :
@bedroomsa la valeurNULL. La variante de requête plie les prédicats en fonction de la valeur du paramètre, ce qui permet de générer un plan basé sur l’analyse.SELECT * FROM Properties PLAN PAR VALEUR(ObjectID = 1234, QueryVariantID = 1, optional_predicate(@bedrooms est NULL))
@bedrooms IS NOT NULLSELECT * FROM Properties WHERE bedrooms = @bedrooms PLAN PER VALUE(ObjectID = 1234, QueryVariantID = 2, optional_predicate( @bedrooms is NULL))
Utiliser l’optimisation facultative du plan de paramètres
Pour activer OPPO pour une base de données, les conditions préalables suivantes sont requises :
- La base de données doit utiliser le niveau de compatibilité 170.
- La
OPTIONAL_PARAMETER_OPTIMIZATIONconfiguration configurée au niveau de la base de données doit être activée.
La OPTIONAL_PARAMETER_OPTIMIZATION configuration étendue à la base de données est activée par défaut. Par conséquent, une base de données utilisant le niveau de compatibilité 170 (la valeur par défaut dans SQL Server 2025 (17.x)) utilise OPPO par défaut.
Vous pouvez vous assurer qu’une base de données utilise OPPO dans SQL Server 2025 (17.x) en exécutant les instructions suivantes :
ALTER DATABASE [<database-name-placeholder>]
SET COMPATIBILITY_LEVEL = 170;
ALTER DATABASE SCOPED CONFIGURATION
SET OPTIONAL_PARAMETER_OPTIMIZATION = ON;
Pour désactiver OPPO pour une base de données, désactivez la configuration délimitée à la OPTIONAL_PARAMETER_OPTIMIZATION base de données :
ALTER DATABASE SCOPED CONFIGURATION
SET OPTIONAL_PARAMETER_OPTIMIZATION = OFF;
Utiliser l’optimisation facultative du plan de paramètres via l’indicateur de requête
Utilisez l'indice de requête DISABLE_OPTIONAL_PARAMETER_OPTIMIZATION pour désactiver OPPO pour une requête spécifique. Spécifiez l’indicateur via la USE HINT clause. Pour plus d’informations, consultez indicateurs de requête.
Cet indicateur fonctionne sous n’importe quel niveau de compatibilité et remplace la configuration délimitée par la OPTIONAL_PARAMETER_OPTIMIZATION base de données.
Spécifiez l’indicateur DISABLE_OPTIONAL_PARAMETER_OPTIMIZATION de requête directement dans la requête ou via les indicateurs de Query Store.
Événements étendus
Utilisez les événements étendus suivants pour la résolution des problèmes et les diagnostics. Ces événements ne sont pas nécessaires pour utiliser la fonctionnalité.
optional_parameter_optimization_skipped_reason: se produit lorsque OPPO décide qu’une requête n’est pas éligible à l’optimisation. Cet événement étendu suit le même modèle que celui utilisé par l'optimisation PSP pour l'événementparameter_sensitive_plan_optimization_skipped_reason. Étant donné qu’une requête peut générer des variantes de requête PSP et OPPO, vérifiez les deux événements pour comprendre pourquoi une ou aucune fonction n’est activée.La requête suivante montre toutes les raisons possibles pour lesquelles le PSP a été ignoré :
SELECT map_value FROM sys.dm_xe_map_values WHERE [name] = 'opo_skipped_reason_enum' ORDER BY map_key;query_with_optional_parameter_predicate: Cet événement étendu suit le même modèle que celui utilisé par l'optimisation PSP pour l'événementquery_with_parameter_sensitivity. Il inclut les champs supplémentaires disponibles dans les améliorations apportées à l’optimisation PSP.Ces champs s’affichent :
- le nombre de prédicats que la fonctionnalité a trouvé intéressant,
- plus d’informations au format JSON concernant les prédicats intéressants et
- si OPPO est pris en charge pour le prédicat ou les prédicats.
Remarks
- ShowPlan XML pour une variante de requête ressemble à l’exemple suivant. Les prédicats sélectionnés par la fonctionnalité ont leurs informations respectives ajoutées à l’indicateur
PLAN PER VALUE(optional_predicate).
<Batch>
<Statements>
<StmtSimple StatementCompId="4" StatementEstRows="1989" StatementId="1" StatementOptmLevel="FULL" StatementOptmEarlyAbortReason="GoodEnoughPlanFound" CardinalityEstimationModelVersion="170" StatementSubTreeCost="0.0563916" StatementText="SELECT PropertyId, AgentId, ListingPrice, ZipCode, SquareFootage, 
 Bedrooms, Bathrooms, ListingDescription
 FROM dbo.Property 
 WHERE (@AgentId IS NULL OR AgentId = @AgentId)
 AND (@ZipCode IS NULL OR ZipCode = @ZipCode)
 AND (@MinPrice IS NULL OR ListingPrice >= @MinPrice)
 AND (@HasDescription IS NULL OR 
 (@HasDescription = 1 AND ListingDescription IS NOT NULL) OR
 (@HasDescription = 0 AND ListingDescription IS NULL)) option (PLAN PER VALUE(ObjectID = 1269579561, QueryVariantID = 7, optional_predicate(@MinPrice IS NULL),optional_predicate(@ZipCode IS NULL),optional_predicate(@AgentId IS NULL)))" StatementType="SELECT" QueryHash="0x2F701925D1202A9F" QueryPlanHash="0xBA0B2B1A18AF1033" RetrievedFromCache="true" StatementSqlHandle="0x09000033F4BE101B2EE46B1615A038D422710000000000000000000000000000000000000000000000000000" DatabaseContextSettingsId="1" ParentObjectId="1269579561" StatementParameterizationType="1" SecurityPolicyApplied="false">
<StatementSetOptions ANSI_NULLS="true" ANSI_PADDING="true" ANSI_WARNINGS="true" ARITHABORT="true" CONCAT_NULL_YIELDS_NULL="true" NUMERIC_ROUNDABORT="false" QUOTED_IDENTIFIER="true" />
<Dispatcher>
<OptionalParameterPredicate>
<Predicate>
<ScalarOperator ScalarString="[@MinPrice] IS NULL">
<Compare CompareOp="IS">
<ScalarOperator>
<Identifier>
<ColumnReference Column="@MinPrice" />
</Identifier>
</ScalarOperator>
<ScalarOperator>
<Const ConstValue="NULL" />
</ScalarOperator>
</Compare>
</ScalarOperator>
</Predicate>
</OptionalParameterPredicate>
<OptionalParameterPredicate>
<Predicate>
<ScalarOperator ScalarString="[@ZipCode] IS NULL">
<Compare CompareOp="IS">
<ScalarOperator>
<Identifier>
<ColumnReference Column="@ZipCode" />
</Identifier>
</ScalarOperator>
<ScalarOperator>
<Const ConstValue="NULL" />
</ScalarOperator>
</Compare>
</ScalarOperator>
</Predicate>
</OptionalParameterPredicate>
<OptionalParameterPredicate>
<Predicate>
<ScalarOperator ScalarString="[@AgentId] IS NULL">
<Compare CompareOp="IS">
<ScalarOperator>
<Identifier>
<ColumnReference Column="@AgentId" />
</Identifier>
</ScalarOperator>
<ScalarOperator>
<Const ConstValue="NULL" />
</ScalarOperator>
</Compare>
</ScalarOperator>
</Predicate>
</OptionalParameterPredicate>
</Dispatcher>
<QueryPlan DegreeOfParallelism="1" CachedPlanSize="40" CompileTime="1" CompileCPU="1" CompileMemory="376" QueryVariantID="7">
Exemple de sortie de l’événement
query_with_optional_parameter_predicateétendu :Field Value optional_parameter_optimization_supportedTrue optional_parameter_predicate_count3 predicate_details{"Predicates":[{"Skewness":1005.53},{"Skewness":1989.00},{"Skewness":1989.00}]}query_type193
Éligibilité et limitations des requêtes
OPPO s’applique uniquement aux requêtes éligibles à l’optimisation Multiplan. La fonctionnalité n’est pas appliquée dans les scénarios suivants :
- Requêtes qui utilisent des variables locales au lieu de paramètres
- Requêtes compilées avec
OPTION (RECOMPILE) - Requêtes exécutées avec
SET ANSI_NULLS OFF - Instructions paramétrables automatiquement
Contenu connexe
- Guide d’architecture de traitement des requêtes
- Recompilation des plans d’exécution
- Paramètres et réutilisation du plan d’exécution
- Paramétrage simple
- Paramétrage forcé
- Indicateurs de requête (Transact-SQL)
- Traitement de requêtes intelligent dans les bases de données SQL
- Sensibilité des paramètres
- MODIFIER LA CONFIGURATION DE L’ÉTENDUE DE LA BASE DE DONNÉES (Transact-SQL)