web-dev-qa-db-fra.com

Dégradation de performances de Microsoft SQL Server 2016 pour la procédure stockée appelée 1000 fois

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é:

  • Changer pour sélectionner non mise à jour
  • Jouer avec degrés de parallélisme (maxdop)
  • Mise à jour des statistiques et recompilation, même le faire à mi-parcours
  • Divers changements dans les index
  • Réinitialisation de la connexion de la connexion en appelant C # Code après x quantité d'itérations
  • Supprimer des contrôles de transactions

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.

4
acg

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

  • Pour un petit nombre de requêtes révélant le problème, utilisez un indice QueryTraceon (9481).
  • Si vous ne voulez pas jouer, alors avez simplement le drapeau de trace 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
5
Kin Shah