Un formulaire qui s'affiche en moins d'une seconde sur un réseau local prend cinq secondes sur un VPN, alors qu'une copie de fichier sur le même lien tourne à pleine vitesse. La différence n'est pas la bande passante. Le formulaire attend une séquence de réponses et paie l'aller-retour complet à chaque étape, tandis que la copie de fichier maintient les octets en mouvement en continu. Comptez ces attentes avant de toucher à la ligne d'accès.

Le symptôme est un écran, pas une requête

Chaque requête de cet écran peut être rapide et l'écran peut rester lent, car le total est la somme des attentes et non la somme des temps d'exécution. Une instruction qui s'exécute en deux millisecondes coûte encore un aller-retour complet lorsque le client doit recevoir son résultat avant d'envoyer la suivante. Sur un chemin avec quarante millisecondes de latence, cent appels dépendants totalisent environ quatre secondes avant que le moindre travail de rendu ne commence. Cette arithmétique est un modèle de l'attente, pas une mesure de votre lien.

C'est pourquoi un test de débit paraît innocent. Le transfert massif mesure le débit, un formulaire bavard mesure la latence, et un VPN peut être excellent dans l'un et ordinaire dans l'autre. Diagnostiquer l'écran signifie donc mesurer l'écran et non le lien.

Enregistrez le temps de bout en bout d'une action utilisateur avant de changer quoi que ce soit. Ce nombre est la seule référence qui puisse vous dire si une correction ultérieure a fonctionné.

Comptez les attentes séquentielles dans une action utilisateur

Instrumentez le client au lieu de deviner. Dans psql, \timing on affiche le temps écoulé de chaque instruction, et EXPLAIN (ANALYZE, BUFFERS) montre quelle part de ce temps le serveur a réellement passée sur le travail.

L'écart entre ces deux nombres est votre surcoût réseau et client. Si une instruction s'exécute en deux millisecondes et que le client enregistre soixante, les cinquante-huit restantes sont du trajet et du traitement local, et aucun index ne les supprimera. Répétez cette comparaison pour chaque instruction émise par l'écran et additionnez les écarts plutôt que les temps d'exécution.

Notez le résultat comme un nombre d'attentes séquentielles. C'est la grandeur que les deux sections suivantes peuvent réduire, et c'est un nombre que vous pouvez discuter avec des preuves.

Regroupez les appels indépendants, conservez les dépendants

Deux instructions qui ne lisent pas les résultats l'une de l'autre peuvent voyager ensemble et être collectées une seule fois, ce qui transforme deux attentes en une. Deux instructions dont la seconde a besoin de la valeur de la première ne le peuvent pas, car la dépendance est réelle et le regroupement changerait ce que fait le programme. Triez les appels dans ces deux piles avant de réécrire quoi que ce soit, et la taille de chaque pile vous dit ce qui est possible.

Le travail par ensembles élimine les attentes plus profondément que le regroupement. Une requête qui renvoie les lignes qu'une boucle ramenait une par une élimine la boucle ainsi que les allers-retours. Cherchez d'abord la boucle, car c'est généralement le plus gros gain et le changement le plus facile à relire.

Un lot doit encore préserver le traitement des erreurs et les frontières de transaction. Concaténer des instructions sans rapport dans une seule chaîne n'est pas une optimisation sûre, et un lot qui cache une instruction échouée derrière une soumission réussie est pire que les attentes qu'il a économisées.

Réutilisez les connexions avant d'acheter de la bande passante

Une nouvelle connexion coûte la résolution de nom, une poignée de main TCP, une négociation TLS et une authentification, et sur un chemin à forte latence chacun de ces éléments est un aller-retour de plus avant la première requête. Les pools de connexions existent pour payer ce coût une fois par processus plutôt qu'une fois par appel.

Dans ADO.NET, fermer ou supprimer une connexion du pool la renvoie pour réutilisation au lieu d'en ouvrir une nouvelle physique, si bien que le schéma qui ressemble à une fuite est souvent le bon usage. Vérifiez que le pool est réellement utilisé au lieu de le supposer : journalisez la création des connexions physiques, ou surveillez le nombre de sessions sur le serveur pendant que l'écran tourne. Les conseils de performance SQL disent la même chose sur la réduction des allers-retours et le regroupement des appels ad hoc fréquents, avec des exemples propres au service que vous devez transposer à votre propre déploiement.

Le regroupement supprime le coût de mise en place et laisse intactes les attentes séquentielles des requêtes. C'est un préalable à une mesure propre, pas une correction en soi.

Pesez le déplacement de l'exécution plus près des données

Exécuter l'application près de la base de données remplace de nombreux échanges distants avec la base par une seule session d'affichage distante. Pour une charge bavarde, cela peut être un changement important, et c'est un changement opérationnel autant qu'un changement de performance : la gestion des sessions, le contrôle d'accès, le déploiement logiciel et l'expérience utilisateur se déplacent tous avec l'application.

Mesurez l'interface réelle et les données qu'elle transfère avant de supposer qu'une direction est plus rapide. Une session de bureau distant déplace des pixels, et un écran à graphisme dense peut se comporter plus mal sur le même chemin que les requêtes qu'il a remplacées, surtout lorsque le client redessine en continu.

Répétez ensuite l'action initiale et comparez trois nombres : attentes séquentielles, volume de résultats et temps d'achèvement de bout en bout. Une amélioration qui modifie la tâche utilisateur mesurée tout en préservant l'exactitude des données et la politique d'accès est celle qui mérite d'être conservée.

Articles similaires