Contexte :
Petite table, procédure stockée pour mettre à jour la table, deux mille mille hits aucun problème. Après ces premiers coups, il commence à ramper à un rythme d'escargots. Cette procédure stockée n'a aucun problème dans notre environnement actuel de SQL Server 2008 R2 avec l'application C # appelante. Dans notre nouvel environnement de test pour SQL Server 2016, nous voyons ce problème. La section incriminée de la requête traite avec une liste des clauses qui comporte quatre comparaisons d'une colonne n'équivivant pas un paramètre de mise à jour de la petite table:
WHERE A.Column1 <> @param1 OR A.Column2 <> @param2 etc..
Mon hypothèse était un paramètre reniflant mais a déclaré cela avec diverses notes de requête.
J'ai aussi essayé:
Le seul changement qui semble remédier à la question est de supprimer la clause WHERE et de pousser la logique sur le setter:
SET A.Column1 = CASE
WHEN A.Column1 <> @param1
THEN @param1
ELSE A.Column1
END
Je n'aime pas avoir à changer le code, mais je n'ai trouvé aucune autre ressource en ligne qui pourrait répondre à la raison pour laquelle SQL Server 2016 se casserait.
Toute aide serait appréciée.
Dans SQL Server 2014 & UP, une nouvelle logique d'estimation de la cardinalité a été introduite.
De bol:
La logique d'estimation de la cardinalité, appelée l'estimateur de Cardinalité, est ré-conçue dans SQL Server 2014 pour améliorer la qualité des plans de requête et améliorer ainsi la performance de la requête. Le nouvel estimateur de Cardinalité intègre des hypothèses et des algorithmes qui fonctionnent bien sur modern OLTP et des charges de travail de l'entreposage de données. Il repose sur une étude d'estimation de cardinalité en profondeur sur les charges de travail modernes et nos apprentissages au cours des 15 dernières années. d'améliorer l'estimateur de cardinalité SQL Server. Les commentaires des clients montrent que, tandis que la plupart des requêtes bénéficieront de la modification ou restent inchangées, Un petit nombre peut afficher des régressions par rapport à l'estimateur de cardinalité précédent .
Récemment, nous mettons à jour de SQL Server 2012 vers SQL Server 2014 et ont été touchés par les nouvelles requêtes de Cardinality Estimator Server - Timing Out, la CPU neige près de 100%.
Après de nombreux problèmes de dépannage, mettez en train de mettre à jour des statistiques, de la reconstruction des index, de faire une analyse du plan de requête, nous avons constaté que l'évolution du niveau de compatibilité vers SQL 2012 fonctionne bien.
Paul White explique Estimation de cardinalité pour plusieurs prédicats
Le calcul de sélectivité dans SQL Server 2014 se comporte de même que les versions précédentes (et le drapeau de trace 4137 fonctionne comme avant) si le niveau de compatibilité de la base de données est inférieur à 120, ou si le drapeau de trace 9481 est actif.
Alors mon avantage serait
TF9481
En tant que paramètre de démarrage, il est donc persisté pendant les redémarrages du serveur.Remarque: Activation TF 9481
, vous n'avez pas besoin de définir le niveau de compatibilité de la base de données à un niveau inférieur.
De - kb280141 :
9481: Utiliser lors de l'exécution de SQL Server 2014 avec le niveau de compatibilité de la base de données par défaut 120. Drapeau de trace 9481 oblige l'optimiseur de requêtes à utiliser la version 70 (version SQL Server 2012) de l'estimateur de cardinalité lors de la création du plan de requête.
En tant que note latérale, avec des tests appropriés - vous voulez aussi regarder TF4199
(Pensez-y comme une clé principale pour activer chaque correctif pour l'optimiseur de requête). Changements de comportement TF4199 avec SQL Server 2016. . TF4199 a aidé dans mon environnement au lot et est par défaut pour toutes les nouvelles installations.
Dans SQL Server 2016, vous n'avez pas besoin d'allumer le drapeau de trace 9481
.
SELECT name, value
FROM sys.database_scoped_configurations
WHERE name = 'LEGACY_CARDINALITY_ESTIMATION';
-- if above is having value = 0, then set to ON
ALTER DATABASE
SCOPED CONFIGURATION
SET LEGACY_CARDINALITY_ESTIMATION = ON;
go
Pour le drapeau de trace 4199
, vous pouvez juste faire
ALTER DATABASE
SCOPED CONFIGURATION
SET QUERY_OPTIMIZER_HOTFIXES = ON