Présentation
Entre 1998 et début 2014, SQL Server a utilisé un estimateur de cardinalité (CE), mais introduirait un nouveau niveau de compatibilité de base de données avec chaque nouvelle version majeure de SQL Server (à l'exception de SQL Server 2008 R2). Les niveaux de compatibilité natifs pour SQL Server sont présentés par version majeure de SQL Server dans le tableau 1 :
Version SQL Server | Niveau de compatibilité natif |
---|---|
SQL Server 7.0 | 70 |
SQL Server 2000 | 80 |
SQL Server 2005 | 90 |
SQL Server 2008 SQL Server 2008 R2 | 100 |
SQL Server 2012 | 110 |
SQL Server 2014 | 120 |
SQL Server 2016 | 130 |
SQL Server 2017 | 140 |
SQL Server 2019 | 150 |
Tableau 1 :Versions de SQL Server et niveaux de compatibilité natifs
Entre SQL Server 7.0 et SQL Server 2012, il n'y avait aucun lien entre le niveau de compatibilité d'une base de données et l'estimateur de cardinalité que les requêtes dans cette base de données utiliseraient. En effet, il n'y avait qu'un seul estimateur de cardinalité, qui a reçu une mise à jour majeure en 1998. Le niveau de compatibilité d'une base de données n'était utilisé que pour la rétrocompatibilité fonctionnelle et pour activer/désactiver certaines nouvelles fonctionnalités dans chaque nouvelle version de SQL Server (voir ceci Réponse de Stack Exchange pour des exemples de la façon dont le comportement a changé entre 80 et 90, probablement le changement le plus perturbateur). Contrairement à la version de fichier d'une base de données SQL Server, vous pouvez modifier le niveau de compatibilité d'une base de données à tout moment, à n'importe quel niveau de compatibilité pris en charge, avec une simple commande ALTER DATABASE.
Par défaut, si vous avez créé un nouveau base de données dans SQL Server 2012, le niveau de compatibilité serait défini sur 110, mais vous pouvez le modifier à un niveau antérieur si vous le souhaitez. Si vous avez restauré une sauvegarde de base de données d'une instance SQL Server 2008 sur une instance SQL Server 2012, cela mettrait à niveau la version de fichier de la base de données, mais laisserait le niveau de compatibilité où il se trouvait sur l'instance SQL Server 2008 (sauf s'il était de 80, ce qui être mis à niveau vers 90, la version minimale prise en charge par SQL Server 2012). En plus de connaître la différence fondamentale entre la version de fichier d'une base de données et le niveau de compatibilité d'une base de données, la plupart des DBA et des développeurs n'avaient pas à se soucier beaucoup des niveaux de compatibilité de la base de données avant la sortie de SQL Server 2014. Dans de nombreux cas, la plupart des bases de données n'ont jamais vu leurs niveaux de compatibilité modifiés après une migration vers une nouvelle version de SQL Server. Cela ne causait généralement aucun problème, sauf si vous aviez réellement besoin d'une nouvelle fonctionnalité ou d'un nouveau comportement qui a changé dans le dernier niveau de compatibilité de la base de données.
Modifications de SQL Server 2014
Cet ancien état de fait a radicalement changé avec la sortie de SQL Server 2014. SQL Server 2014 a introduit un « nouvel » estimateur de cardinalité qui a été activé par défaut lorsqu'une base de données était au niveau de compatibilité 120. Dans le livre blanc classique, "Optimisation de vos plans de requête avec l'estimateur de cardinalité SQL Server 2014", Joe Sack explique le contexte et le comportement de ce changement en avril 2014. Dans de nombreux cas, la plupart de vos requêtes s'exécutaient plus rapidement lors de l'utilisation de la nouvelle cardinalité. estimateur, mais il était assez courant de rencontrer des requêtes présentant des régressions de performances majeures avec le nouvel estimateur de cardinalité. Si cela se produisait, SQL Server 2014 n'avait pas autant d'options pour atténuer les problèmes de performances causés par le nouveau CE. Le livre blanc de Joe couvre ces options en détail, mais essentiellement, vous étiez limité aux indicateurs de trace au niveau de l'instance ou aux conseils de requête au niveau de la requête pour contrôler quel estimateur de cardinalité était utilisé par l'optimiseur de requête, sauf si vous vouliez revenir au niveau de compatibilité 110 ou inférieur .
Modifications de SQL Server 2016
SQL Server 2016 a introduit des options de configuration étendues à la base de données, qui vous permettent de contrôler certains comportements qui étaient auparavant configurés au niveau de l'instance, à l'aide d'une commande ALTER DATABASE SCOPED CONFIGURATION. Dans SQL Server 2016, ces options comprenaient MAXDOP, LEGACY_CARDINALITY ESTIMATION, PARAMETER_SNIFFING et QUERY_OPTIMIZER_HOTFIXES. Il y avait aussi une option CLEAR PROCEDURE_CACHE qui vous permettait d'effacer tout le cache du plan pour une seule base de données.
Les options de configuration étendues à la base de données LEGACY_CARDINALITY ESTIMATION et QUERY_OPTIMIZER_HOTFIXES sont les plus pertinentes dans ce contexte. LEGACY_CARDINALITY ESTIMATION active le CE hérité quel que soit le paramètre de niveau de compatibilité de la base de données. Il équivaut à l'indicateur de trace 9481, mais il n'affecte que la base de données en question, pas l'instance entière. Il vous permet de définir le niveau de compatibilité de la base de données sur 130 afin d'obtenir un certain nombre d'avantages fonctionnels et de performances, tout en utilisant l'ancienne base de données CE à l'échelle de la base de données (sauf si elle est remplacée par un indicateur de requête au niveau de la requête).
L'option QUERY_OPTIMIZER_HOTFIXES équivaut à l'indicateur de trace 4199 au niveau de la base de données. SQL Server 2016 activera tous les correctifs de l'optimiseur de requête avant SQL Server 2016 RTM lorsque vous utilisez le niveau de compatibilité de base de données 130 (sans activer l'indicateur de trace 4199). Si vous activez TF 4199 ou activez QUERY_OPTIMIZER_HOTFIXES, vous obtiendrez également tous les correctifs de l'optimiseur de requête qui ont été publiés après SQL Server 2016 RTM.
SQL Server 2016 SP1 a également introduit les indicateurs de requête USE HINT qui sont plus faciles à utiliser, à comprendre et à mémoriser que les anciens indicateurs de requête QUERYTRACEON. Cela vous donne un contrôle encore plus précis sur le comportement de l'optimiseur lié au niveau de compatibilité de la base de données et à la version de l'estimateur de cardinalité utilisé. Vous pouvez interroger sys.dm_exec_valid_use_hints pour obtenir une liste des noms USE HINT valides pour la version exacte de SQL Server que vous exécutez.
Modifications de SQL Server 2017
La nouvelle fonctionnalité de traitement adaptatif des requêtes a été ajoutée dans SQL Server 2017 et est activée par défaut lorsque vous utilisez le niveau de compatibilité de base de données 140.
Microsoft essaie de s'éloigner de l'ancienne terminologie de "Nouveau CE" et "Ancien CE", car il existe en fait des modifications et des correctifs pour l'optimisation des requêtes dans chaque nouvelle version majeure de SQL Server. Pour cette raison, il n'y a plus de "Nouveau CE" unique. Au lieu de cela, Microsoft souhaite faire référence à CE70 (CE par défaut pour SQL Server 7.0 à SQL Server 2012), CE120 pour SQL Server 2014, CE130 pour SQL Server 2016, CE140 pour SQL Server 2017 et CE150 pour SQL Server 2019. 2017 CU10, vous pouvez utiliser la fonctionnalité USE HINT pour contrôler cela avec des conseils de requête. Par exemple :
/*...query...*/ OPTION (USE HINT('QUERY_OPTIMIZER_COMPATIBILITY_LEVEL_130'));
… serait un indice de requête valide pour forcer l'estimateur de cardinalité CE130 pour une requête particulière.
Modifications de SQL Server 2019
SQL Server 2019 ajoute encore plus d'améliorations de performances et de changements de comportement qui sont activés par défaut lorsqu'une base de données utilise le mode de compatibilité 150. Un excellent exemple est l'intégration UDF scalaire. Un autre exemple est la fonctionnalité de traitement intelligent des requêtes, qui est un sur-ensemble du traitement adaptatif des requêtes dans SQL Server 2017.
Il existe cinq nouvelles options USE HINT, y compris des moyens de désactiver le mode batch ou de désactiver la rétroaction d'attribution de mémoire adaptative, comme indiqué dans le tableau 2 :
DISABLE_BATCH_MODE_ADAPTIVE_JOINS |
DISABLE_BATCH_MODE_MEMORY_GRANT_FEEDBACK |
DISABLE_INTERLEAVED_EXECUTION_TVF |
DISALLOW_BATCH_MODE |
QUERY_OPTIMIZER_COMPATIBILITY_LEVEL_150 |
Table 2 :Nouvelles options USE HINT
Et il existe également seize nouvelles options de configuration étendues à la base de données (à partir de CTP 2.2) qui vous permettent de contrôler au niveau de la base de données davantage d'éléments qui sont également affectés par les indicateurs de trace ou le niveau de compatibilité de la base de données. Il vous donne un contrôle plus précis des modifications de niveau supérieur qui sont activées par défaut avec le niveau de compatibilité de base de données 150. Celles-ci sont répertoriées dans le tableau 3 :
ACCELERATED_PLAN_FORCING | ELEVATE_RESUMABLE | ROW_MODE_MEMORY_GRANT_FEEDBACK |
BATCH_MODE_ADAPTIVE_JOINS | GLOBAL_TEMPORARY_TABLE_AUTO_DROP | TSQL_SCALAR_UDF_INLINING |
BATCH_MODE_MEMORY_GRANT_FEEDBACK | INTERLEAVED_EXECUTION_TVF | XTP_PROCEDURE_EXECUTION_STATISTICS |
BATCH_MODE_ON_ROWSTORE | ISOLATE_SECURITY_POLICY_CARDINALITY | XTP_QUERY_EXECUTION_STATISTICS |
DEFERRED_COMPILATION_TV | LIGHTWEIGHT_QUERY_PROFILING | |
ELEVATE_ONLINE | OPTIMIZE_FOR_AD_HOC_WORKLOADS |
Tableau 3 :Nouvelles options de configuration étendues à la base de données
Conclusion
La migration vers une version moderne de SQL Server (c'est-à-dire SQL Server 2016 ou plus récent) est beaucoup plus compliquée qu'elle ne l'était avec les anciennes versions de SQL Server. En raison des changements associés aux différents niveaux de compatibilité de la base de données et aux différentes versions de l'estimateur de cardinalité, il est en fait très important de réfléchir, de planifier et de tester réellement le niveau de compatibilité de la base de données que vous souhaitez utiliser sur la nouvelle version de SQL Server que vous migrez vos bases de données existantes vers.
Le processus de mise à niveau recommandé par Microsoft consiste à mettre à niveau vers la dernière version de SQL Server, mais en conservant le niveau de compatibilité de la base de données source. Ensuite, activez Query Store sur chaque base de données et collectez des données de base sur la charge de travail. Ensuite, vous définissez le niveau de compatibilité de la base de données sur la dernière version, puis utilisez le magasin de requêtes pour corriger les régressions de performances en forçant le dernier bon plan connu.
Vous voulez vraiment éviter une migration "aveugle" au hasard où vous ignorez parfaitement comment cela fonctionne et comment votre charge de travail réagira à ces changements. La modification du niveau de compatibilité de la base de données vers une version appropriée et l'utilisation des options de configuration de portée de base de données appropriées, ainsi que des conseils de requête appropriés lorsque cela est absolument nécessaire, sont extrêmement importants avec les versions modernes de SQL Server.