Database
 sql >> Base de données >  >> RDS >> Database

Différents forfaits pour des serveurs identiques

Dans mon dernier message, "Plusieurs plans pour une requête 'identique'", j'ai parlé du cas où vous obtenez deux plans différents pour ce que vous pensez être la même requête, ainsi que du cas où vous obtenez deux copies du idem planifier (et peut-être même ne pas le savoir). Comme nous l'avons examiné, "identique" peut être un mot assez fort.

Un autre scénario qui jette les gens dans une boucle est le cas où ils restaurent une base de données sur un serveur différent - par exemple, restaurent une base de données de production sur un serveur de test "identique" - et qu'ils obtiennent des caractéristiques de performances différentes ou des plans différents pour la même requête (pas guillemets cette fois - je parle vraiment de requêtes vraiment identiques).

Les serveurs sont-ils vraiment "identiques" ?

Ces gars peuvent sembler similaires, mais ils ne sont pas tout à fait identiques.

Si vous rencontrez ce scénario, la première chose que vous devez vous demander est de savoir si ces deux serveurs sont vraiment identiques. Quelques points à vérifier :

  • Version – De nombreuses modifications du comportement de l'optimiseur et des requêtes sont transmises via les service packs et les mises à jour cumulatives. J'ai souvent vu des gens dire :"Eh bien, ils sont tous les deux en 2008 !" - alors qu'en fait, l'un était 2008 et l'autre était 2008 R2, ou ils étaient à différents service packs ou même à des niveaux de mise à jour cumulés. Étant donné que de nombreuses personnes lisant @@VERSION confondent les informations sur le service pack du système d'exploitation avec les informations sur le service pack SQL Server, je dirais que ce qui suit est préférable:

    SELECT SERVERPROPERTY (N'ProductVersion' );

    Je ne saurais trop insister sur l'importance d'utiliser exactement la même version pour effectuer de véritables tests de pommes à pommes. Si vous utilisez SQL Server 2012 ou une version ultérieure, vous pouvez consulter nos publications sur les versions (SQL Server 2012 | SQL Server 2014) pour déterminer le service pack ou la mise à jour cumulative requis pour vous assurer que les versions correspondent.

  • Édition – Bien que vous utilisiez, espérons-le, la même édition sur les deux serveurs (ou l'équivalent, car à part la licence, Developer et Evaluation sont les mêmes que Enterprise), les incompatibilités ici peuvent conduire à un comportement très différent. Par exemple, différentes éditions ont des capacités de calcul différentes pour diverses fonctionnalités, puis il y a des choses plus subtiles comme la possibilité d'utiliser une vue indexée sans l'indice NOEXPAND ou d'effectuer des modifications de schéma ou la maintenance d'index en ligne. Vous pouvez comparer les éditions en utilisant :

    SELECT SERVERPROPERTY (N'Edition' );

  • Nombre de processeurs - SQL Server utilise définitivement le nombre de planificateurs disponibles pendant le processus de production d'un plan d'exécution, et il est indéniable que le nombre de cœurs peut affecter les performances d'exécution réelles (laissons de côté la vitesse d'horloge, car c'est rarement un facteur significatif dans la requête performance). Ne vous contentez pas de valider le nombre de cœurs physiquement installés sur le serveur sous-jacent, mais vérifiez également le journal des erreurs de SQL Server pour connaître le nombre de processeurs que SQL Server peut réellement utiliser en raison des licences. Même en oubliant le nombre de cœurs bruts, sur un système NUMA, des restrictions artificielles ici peuvent conduire à des profils de performances très différents. Pour plus d'informations, consultez le récent article de Brent Ozar, "Why Core-Based Licensing Matters for Performance Tuning". L'édition est également liée ici, car dans SQL Server 2012 et 2014, l'édition Standard ne peut utiliser que 16 cœurs, quels que soient vos paramètres ou votre matériel physique. Parmi les autres paramètres susceptibles d'influencer différemment le choix du plan basé sur le processeur et les performances, citons le gouverneur de ressources, le MAXDOP à l'échelle du serveur, l'affinité du processeur et le seuil de coût pour le parallélisme.
  • Quantité de mémoire – Comme les processeurs, l'optimiseur effectue des choix de plan en fonction de la quantité de mémoire disponible. Et comme les processeurs, je ne parle pas seulement de la quantité de RAM installée dans le système, mais de la quantité de mémoire accordée à SQL Server et de la quantité qu'il utilise réellement. Vérifiez les paramètres de mémoire maximale du serveur, mais également les compteurs de performances pour la mémoire totale et cible, et même DBCC MEMORYSTATUS. D'autres choses que vous voudrez peut-être revoir incluent les paramètres du gouverneur de ressources et les pages de verrouillage en mémoire. Il existe également un paramètre qui, s'il est différent entre deux serveurs, peut avoir un effet significatif sur la quantité de cache de plan utilisée pour le même ensemble de requêtes :optimiser pour les charges de travail ad hoc. Kimberly Tripp a un excellent article à ce sujet :Planifiez le cache et optimisez-le pour les charges de travail ad hoc. Enfin, si le serveur est virtuel, sachez que l'environnement peut jouer un rôle ici, en particulier lorsque les paramètres de mémoire de la machine virtuelle ne correspondent pas à la production ou sont dynamiques.
  • Pool de mémoire tampon/cache de plan – Lorsque vous restaurez la base de données sur le serveur de test, il y a un tas de choses qui ne sont tout simplement pas prêtes pour vous tout de suite. Le pool de mémoire tampon ne contient aucune des données qui auraient pu exister sur le serveur source. Des E/S supplémentaires seront donc nécessaires pour amorcer les données en mémoire la première fois qu'elles seront interrogées. Et si le pool de mémoire tampon est restreint différemment de la production en raison de certains des facteurs ci-dessus, il peut ne pas être possible d'obtenir les mêmes modèles de performances même après avoir exécuté la requête plusieurs fois - Paul White (@SQL_Kiwi) en parle dans sa réponse sur Administrateurs de bases de données. De plus, le cache du plan ne contiendra aucun des plans qui existaient en production, donc à tout le moins - même si le même plan est finalement compilé (ce qui peut ne pas se produire en raison de paramètres différents de ceux lorsque le plan a été compilé sur l'original serveur) – vous aurez des frais de compilation supplémentaires. Et ceux-ci peuvent changer si vous avez également mis en place des indicateurs de trace affectant le plan.
  • Sous-système de disque – Bien que la vitesse et la taille du ou des disques utilisés n'affectent pas directement le choix du plan, elles peuvent certainement influencer les performances observées, ce qui peut vous amener à vous demander pourquoi la même requête, avec le même plan, s'exécute tellement plus rapidement sur un système que l'autre. Les E/S sont généralement le plus gros goulot d'étranglement de SQL Server, et il est assez rare qu'un serveur de test ait exactement le même sous-système sous-jacent que son équivalent de production. Donc, si vous constatez des différences de performances entre les deux systèmes et que les plans et autres éléments matériels sont identiques, cela pourrait être le meilleur endroit à vérifier. Et n'oubliez pas qu'à partir de SQL Server 2014, le gouverneur de ressources peut imposer des contraintes sur vos performances d'E/S.
  • Indicateurs de suivi – Vérifiez la liste des indicateurs de trace globaux définis sur les deux serveurs ; plusieurs peuvent affecter l'optimisation, le comportement du plan et les performances perçues, même si tous les paramètres ci-dessus sont identiques. En voici 10 courants et notables (bien que ce ne soit absolument pas une approbation pour les activer sans tests de régression approfondis) :

    Signal Explication
    2301 Contraint l'optimiseur à passer plus de temps à essayer de trouver un plan optimal.
    2312 Force le nouvel estimateur de cardinalité de SQL Server 2014.
    2335 Entraîne des allocations de mémoire plus conservatrices.
    2453 Force OPTION (RECOMPILE) pour les requêtes référençant des variables de table.
    2861 Permet à SQL Server de mettre en cache des plans triviaux/à coût nul.
    4136 Effectivement, ajoute OPTIMIZE FOR UNKNOWN à toutes les requêtes (pour contrecarrer le reniflage des paramètres).
    4199 Un parapluie contenant toute une série de correctifs d'optimiseur.
    8744 Désactive la prélecture pour les boucles imbriquées.
    9481 Désactive le nouvel estimateur de cardinalité de SQL Server 2014.


    Cette liste d'indicateurs de trace n'est en aucun cas exhaustive ; il y en a beaucoup d'autres, y compris des sans-papiers qu'on m'a demandé de ne pas mentionner. Si vous en utilisez d'autres non répertoriés ci-dessus (et que vous ne pouvez pas expliquer pourquoi), vous pouvez trouver des indices dans KB #920093, KB #2964518, Trace Flags (MSDN) ou Trace Flags in SQL Server (TechNet). Vous trouverez également des informations précieuses dans divers articles de Paul White, ici ou sur sql.kiwi.

  • Concurrence – Vraisemblablement, le système de test est utilisé pour des choses autres que ce que vous testez actuellement. Et à moins que vous n'effectuiez une relecture quelconque, il a également probablement un profil de charge de travail très différent. Ces différences de charge de travail peuvent évidemment avoir un impact direct sur la disponibilité des ressources pour traiter les requêtes que vous testez, et par conséquent sur les performances perçues de ces requêtes. N'oubliez pas de rechercher d'autres services qui peuvent ne pas exister en production, ou qui existent mais qui sont utilisés de différentes manières (tels que Analysis Services, Reporting Services, les services Windows et même vos propres applications). À l'inverse, il peut y avoir des services comme celui-ci en production qui affectent les performances là-bas, ou une surcharge supplémentaire sur l'instance elle-même qui n'est pas imitée dans le test :en dehors de la charge de travail de production réelle, pensez à des choses comme le traçage, les événements étendus, la surveillance à fort impact, suivi des modifications, capture des données modifiées, audit, courtier de services, maintenance d'index, tâches de sauvegarde, vérifications DBCC, mise en miroir, réplication, groupes de disponibilité, et la liste s'allonge encore et encore…

Les bases de données sont-elles toujours "identiques" ?

En supposant que toutes les variables matérielles et de charge de travail correspondent suffisamment bien, il peut toujours être difficile de s'assurer que les bases de données restent les mêmes. Si vous effectuez une sauvegarde/restauration sur le système de test, la nouvelle base de données démarre identique à la source (à l'exception de l'emplacement physique et de la sécurité). Mais dès que vous commencez à le toucher de quelque manière que ce soit, il s'écarte très rapidement de la copie de production, car vous pouvez faire tout ou partie des actions suivantes :

  • Modifier les données, le schéma ou les deux
  • Lancer par inadvertance une mise à jour automatique des statistiques.
  • Ajouter, défragmenter ou reconstruire manuellement des index, ou créer ou mettre à jour des statistiques
  • Modifiez les paramètres de la base de données tels que le niveau de compatibilité, le niveau d'isolement, le paramétrage forcé, les index XML sélectifs ou l'une des options nommées "Auto"-. (Heck, même les emplacements des données et des fichiers journaux et les paramètres de croissance peuvent affecter les performances des requêtes, et cela inclut tempdb.)
  • Vider le cache du plan, le pool de mémoire tampon, ou les deux, directement ou en tant qu'effet secondaire d'autres événements (tels qu'une RECONFIGURE ou un redémarrage de service).

De plus, une fois que vous avez commencé à générer de nouveaux plans de requête, avant même que l'un des changements ci-dessus n'ait lieu, vous devez vous rappeler qu'ils peuvent être basés sur des données différentes de celles utilisées pour générer des plans pour les mêmes requêtes en production. Par exemple, la cardinalité lorsque le plan a été compilé en production peut avoir été considérablement faussée entre ce point et le moment de la sauvegarde, ce qui signifie que le nouveau plan sera généré sur la base de différentes statistiques et informations d'histogramme.

Ces choses divergent encore plus s'il ne s'agit pas, en fait, d'une restauration récente - mais plutôt de deux schémas et ensembles de données que vous maintenez synchronisés d'une autre manière (comme les déploiements manuels de schémas et/ou de modifications de données, ou même la réplication). En raison des limitations d'espace disque, vous pouvez également n'avoir pris qu'un sous-ensemble de données de production, ou même un clone de statistiques uniquement - ces différences de données entraîneront presque certainement des caractéristiques de performances différentes pour toutes les requêtes sauf les plus simples, même si vous le faites chance et obtenez les mêmes plans pour certains.

Les requêtes sont-elles vraiment "identiques" ?

Même si tout ce qui précède est vérifié, il existe toujours des scénarios dans lesquels vous obtenez un plan différent en raison des paramètres de session (vous utilisez peut-être une copie différente de SSMS, avec des paramètres différents ou un outil client différent), ou des schémas par défaut différents ( vous vous connectez peut-être au serveur de test avec une autre connexion d'authentification Windows ou SQL, par exemple). J'ai beaucoup parlé de ces choses dans mon post précédent.

Conclusion

Bien qu'il existe des moyens d'atténuer certaines différences (consultez DBCC OPTIMIZER_WHATIF pour tromper votre serveur de test en lui faisant croire des choses phénoménales sur le matériel sous-jacent), la vérité est qu'il sera très difficile de faire en sorte que deux serveurs fonctionnent de manière fiable et systématiquement identique, et qu'il existe potentiellement des dizaines de raisons pour lesquelles vous pouvez obtenir des plans différents ou des performances différentes sur deux serveurs similaires (voire identiques).

Avez-vous des astuces particulières ? Avez-vous des points douloureux atroces avec les idées ci-dessus (ou d'autres que j'ai oublié de mentionner) ? Veuillez partager dans les commentaires ci-dessous !