Cette page décrit Calíope 1.7, la version que je construis en ce moment. La 1.6 est sur l'App Store pour Mac, iPad, iPhone, Apple Watch, Apple TV et Apple Vision Pro. Le changelog indique dans quelle version chaque fonction est arrivée.

Ajoute un bouton « Ouvrir dans Calíope » à chaque sujet. Ne fonctionne qu'avec l'app installée.

Requêtes lentes du serveur

Le journal des requêtes lentes

Ce que le serveur a noté de lui-même sur les requêtes ayant dépassé son seuil, pour tous ses clients.

Où le trouver : Espace de travail › Outils › Requêtes lentes

Voici ce que le serveur a noté de lui-même : les requêtes qui ont dépassé son seuil, venant de tous ses clients et pas seulement de Calíope. Le journal des requêtes de l'app est autre chose —ce que vous avez exécuté d'ici— et il a son propre outil.

La barre propose jusqu'à trois vues, et lesquelles existent dépend du serveur : Réglages, toujours ; Entrées, une ligne par exécution, seulement si le moteur conserve les exécutions individuelles et laisse un client les lire ; Par instruction, le résumé groupé par forme de requête, seulement si le moteur le publie. Une vue que le serveur ne peut pas remplir n'est pas dessinée en grisé : elle n'est pas dessinée.

MySQLMariaDBAurora

La famille MySQL donne les deux : mysql.slow_log conserve les exécutions —avec leur heure, leur utilisateur et le texte littéral— et performance_schema conserve le résumé par forme.

PostgreSQL

PostgreSQL ne conserve aucune exécution lisible par un client : son journal part dans un fichier de la machine du serveur. Ce qu'il publie, c'est l'agrégat, via pg_stat_statements, donc vous verrez ici Par instruction et non Entrées.

SQL Server

SQL Server n'a pas de journal des requêtes lentes : ni seuil ni exécutions enregistrées. Ce qu'il tient, toujours et sans rien activer, c'est le décompte de chaque plan de son cache, et c'est ce que vous verrez dans Par instruction. Entrées n'apparaît pas.

Pour voir une ligne entière —le texte complet et tout ce que le serveur a noté— double-cliquez dessus sur le Mac ou touchez-la sur l'iPad. Depuis sa fiche, la requête se copie ou part vers l'éditeur.

Le sélecteur de droite dit combien de lignes sont demandées : cinquante pour voir ce qui se passe maintenant, mille pour examiner la journée entière. L'actualisation automatique relit toutes les dix secondes, et la barre indique à quelle heure ce que vous voyez a été lu.

Oracle

Oracle n'a pas de journal des requêtes lentes : ni seuil du serveur ni exécutions enregistrées une à une. Ce qui est lu, c'est le cache d'instructions (V$SQL), qui tient toujours les chiffres de chaque instruction tant qu'elle y reste. Entrées montre une ligne par instruction à son exécution moyenne —temps, CPU, lectures et lignes divisés par le nombre d'exécutions, affiché à côté— et Par instruction, le résumé groupé par forme. Ce n'est pas un historique : une instruction qui sort du cache disparaît avec ses chiffres, et un redémarrage le vide. Les requêtes internes de SYS et SYSTEM n'apparaissent pas, sauf les vôtres si vous vous connectez avec l'un de ces comptes. Lire V$SQL demande un privilège de dictionnaire (SELECT_CATALOG_ROLE ou SELECT ANY DICTIONARY) ; sans lui, l'écran montre l'erreur du serveur. AWR et les vues DBA_HIST_* ne sont pas consultés : ils exigent un pack payant d'Oracle.

ClickHouse

ClickHouse donne les deux depuis system.query_log : les exécutions, lues juste après un SYSTEM FLUSH LOGS pour que ce qui vient de s'exécuter y soit déjà, et le résumé par forme. Les exécutions incluent celles qui ont échoué, avec leur erreur dans une colonne à part, et donnent les octets lus et la mémoire après le temps ; l'heure est celle de l'horloge du serveur. Masquer celles de Calíope, activé par défaut, masque ce que Calíope interroge de lui-même, jamais ce que vous avez écrit dans l'éditeur.

Apple Vision Pro : comme sur iPad : regardez la ligne et pincez pour l'ouvrir.

Mots-clés : requêtes lentes, slow query log, performance, serveur, seuil, journal

Réglages, moteur par moteur

Activer le journal, déplacer le seuil et choisir où il écrit — là où le serveur permet de le faire d'ici.

Où le trouver : Requêtes lentes › Réglages

Les cartes du haut disent ce que le serveur répond à cet instant : s'il enregistre, avec quel seuil et où il écrit. En dessous apparaît l'une de deux choses : les contrôles pour le changer, ou une note qui dit où cela se change vraiment. Jamais des contrôles grisés, qui ne distinguent pas « pas ici » de « c'est cassé ».

Le seuil se tape ou se déplace avec les boutons moins et plus, et s'envoie avec Appliquer. Un seuil négatif est refusé ici même : aucune requête ne dure moins que rien, et le serveur le ramènerait à zéro sans rien dire — toute requête deviendrait alors lente et le journal grossirait sans frein.

MySQLMariaDBAurora

Le seuil est en secondes (long_query_time), et la destination se choisit entre la table mysql.slow_log, le fichier du serveur, ou les deux (log_output). Seul ce qui va dans la table est lisible depuis un client.

Deux choses qui surprennent : un changement fait d'ici ne survit pas à un redémarrage du serveur —pour cela il va dans son fichier de configuration— et n'atteint pas les connexions déjà ouvertes, celle de Calíope comprise : les sessions vivantes continuent de mesurer avec l'ancienne valeur jusqu'à leur recyclage.

Aurora

Sur Amazon Aurora ces réglages ne vivent pas dans le serveur mais dans le groupe de paramètres du cluster, donc vous verrez ici la note au lieu des contrôles. Vider le journal reste possible : le serveur le fait lui-même avec mysql.rds_rotate_slow_log.

PostgreSQL

Le seuil est en millisecondes (log_min_duration_statement), et un changement fait d'ici persiste : il s'écrit avec ALTER SYSTEM et le serveur recharge sa configuration.

Mais certaines origines l'emportent sans le dire. Si la valeur vient de la ligne de commande avec laquelle le serveur a démarré, ou d'un réglage propre à cette base, à ce rôle ou à cette session, l'écriture est acceptée, le fichier reçoit la nouvelle valeur et celle qui s'applique reste l'ancienne. C'est pourquoi la première variable de la liste du bas est l'origine du seuil : c'est elle qui dit où il faut le changer. Quand l'origine est de celles-là, vous verrez ici la note et non les contrôles.

La destination ne se choisit pas : PostgreSQL écrit toujours dans son propre journal, un fichier de la machine du serveur.

SQL Server

Dans SQL Server, il n'y a rien à régler : le cache des plans compte toujours, et il n'a ni seuil ni destination à choisir. C'est pourquoi la carte du seuil n'apparaît pas et vous verrez la note au lieu des contrôles. Ce qui est lu vit dans la mémoire du serveur : il se perd au redémarrage, et un plan qui quitte le cache emporte ses chiffres. Avec optimize for ad hoc workloads activé, une requête isolée n'entre qu'à sa deuxième exécution.

La liste de la fin regroupe les variables que ce serveur publie autour du journal, avec les noms qu'il leur donne. Elles sont informatives : elles changent là où leurs réglages se changent, pas ici.

Oracle

Dans Oracle, le seuil appartient à Calíope, pas au serveur : il s'applique à la lecture, à l'exécution moyenne de chaque instruction, et il est enregistré dans ce profil. Le changer ne touche rien sur le serveur et vaut dès la lecture suivante. Il est en secondes, bien que le cache compte le temps en microsecondes ; si vous ne l'avez pas changé, c'est une seconde. Il n'y a pas d'interrupteur —le cache ne s'éteint pas— ni de destination à choisir : ce qui est lu vit dans la mémoire du serveur.

ClickHouse

Le serveur garde le seuil en millisecondes (log_queries_min_query_duration_ms), bien qu'ici il s'affiche en secondes, et la destination est toujours system.query_log. L'activation et le seuil s'enregistrent sur votre propre compte, avec ALTER USER … MODIFY SETTINGS, et valent pour les requêtes de ce compte à partir de la suivante, pas pour celles des autres. Si le compte est défini dans la configuration du serveur ou n'a pas ALTER USER, vous verrez la note au lieu des commandes. Vider le journal, c'est TRUNCATE TABLE system.query_log, pour tout le serveur.

Mots-clés : seuil, long_query_time, log_min_duration_statement, log_output, ALTER SYSTEM, parameter group

Le résumé par instruction

Il groupe par forme de requête, pas par exécution : il dit ce qui coûte sa journée au serveur.

Où le trouver : Requêtes lentes › Par instruction

Par instruction ne liste pas des exécutions : il groupe par la forme de la requête. Les littéraux sont remplacés par un marqueur, donc mille requêtes qui ne diffèrent que par la valeur cherchée font une ligne, avec ses appels, son temps total et son temps moyen. C'est la réponse à « qu'est-ce qui coûte sa journée à ce serveur ? », qui n'est presque jamais la requête la plus lente.

MySQLMariaDBAurora

C'est performance_schema qui le publie, et les littéraux sortent en ?. Sur MariaDB il naît désactivé : si cette vue dit qu'il n'y a pas de résumé, ce n'est pas qu'il n'y a pas de requêtes lentes — c'est que performance_schema est à OFF. Il ne s'active pas serveur en marche : cela va dans son fichier de configuration et il faut le redémarrer.

PostgreSQL

C'est pg_stat_statements qui le publie, et les littéraux sortent en $1. Il faut deux choses, toutes deux hors de l'app : la bibliothèque préchargée dans shared_preload_libraries, ce qui exige de redémarrer le serveur, et l'extension créée dans cette base, une fois par base :

CREATE EXTENSION pg_stat_statements;

Si l'extension est créée et la bibliothèque non chargée, la vue existe et ne collecte rien. Ce sont deux états distincts, et l'outil dit lequel.

SQL Server

Il vient de sys.dm_exec_query_stats, regroupé par query_hash, qui est la forme de la requête. Le texte affiché est celui d'une de ses exécutions, avec ses littéraux, pas une forme avec des marqueurs. Le lire demande l'autorisation VIEW SERVER STATE ; sans elle, la vue affiche l'erreur du serveur. Réinitialiser les statistiques n'apparaît pas : vider ce résumé serait DBCC FREEPROCCACHE, qui jette les plans de tout le serveur, et cela ne se fait pas d'ici.

Le résumé est celui du serveur entier, donc les privilèges comptent : là où votre utilisateur ne peut pas lire les requêtes des autres, le serveur renvoie la ligne sans le texte. Quand cela arrive, c'est dit ici avec le nombre —combien de formes de plus vous ne pouvez pas lire—, ce qui est très différent d'une liste vide.

Réinitialiser les statistiques remet ces compteurs à zéro pour tout le serveur, pas pour votre session : cela touche quiconque regarde le même résumé, et c'est irréversible.

Oracle

Il vient de V$SQL, groupé par FORCE_MATCHING_SIGNATURE : deux requêtes qui ne diffèrent que par un littéral forment une ligne, et le texte affiché est celui de l'une d'elles. Les instructions sans cette signature —les blocs PL/SQL, le DDL— sont groupées par leur SQL_ID. Le résumé n'applique pas le seuil, et le maximum est celui de l'exécution moyenne la plus lente parmi celles qu'il groupe : le cache ne garde pas chaque exécution. Réinitialiser les statistiques n'apparaît pas, ni Vider le journal dans Entrées : les deux reviendraient à vider le cache partagé de tout le serveur.

ClickHouse

Il vient de system.query_log, regroupé par normalized_query_hash : deux requêtes qui ne diffèrent que par un littéral font une seule ligne, et le texte affiché est celui de l'une d'elles. Réinitialiser les statistiques vide cette même table, donc emporte aussi les exécutions, et la confirmation le dit.

Mots-clés : résumé, par instruction, performance_schema, pg_stat_statements, normalisée, privilèges

Du journal au Profileur

Le journal dit quelle requête est lente ; pour savoir pourquoi, on l'envoie à l'éditeur et on la profile là-bas.

Où le trouver : Requêtes lentes › clic droit › Envoyer à l'éditeur

Le journal dit quelle requête est lente. Pour savoir pourquoi, la requête doit être réexécutée, et c'est votre décision — pas celle d'une liste qui s'actualise toutes les dix secondes.

Depuis une ligne, par son menu contextuel ou en ouvrant sa fiche, Envoyer à l'éditeur dépose la requête dans l'Éditeur SQL, dans un onglet, sans l'exécuter. Là, vous décidez quoi en faire.

MySQLMariaDBAuroraClickHouse

L'exécuter et appuyer sur Profiler pour voir la répartition par phase, ou demander son plan au moteur avec EXPLAIN visuel.

PostgreSQLSQL ServerOracle

Demander son plan au moteur avec EXPLAIN visuel. Profiler, la répartition par phase, appartient à la famille MySQL et n'apparaît pas ici dans l'éditeur.

Avant d'exécuter ce qu'apporte une ligne, rappelez-vous que le texte est celui qu'a exécuté un autre client, avec ses paramètres et contre la base qu'il avait ouverte.

MySQLMariaDBAuroraPostgreSQL

Et du résumé par instruction, ce qui arrive est la forme normalisée, avec des marqueurs au lieu des valeurs : il faut mettre vos propres valeurs avant de l'exécuter.

SQL ServerClickHouseOracle

Du résumé par instruction, ce qui arrive est le texte d'une de ses exécutions, avec les valeurs de celle-ci : la ligne représente toutes celles de la même forme.

Mots-clés : profiler, profileur, éditeur, explain, plan, envoyer à l'éditeur

Vider le journal et remettre le résumé à zéro

Ce que chaque bouton supprime sur le serveur et avec quels moteurs il apparaît.

Où le trouver : Espace de travail › Outils › Requêtes lentes

Deux boutons suppriment ce que le serveur a enregistré, et aucun ne s’annule.

- Vider le journal, dans Entrées, supprime les exécutions enregistrées.
- Réinitialiser les statistiques, dans Par instruction, remet à zéro le résumé de tout le serveur, pas seulement le vôtre.

Les deux confirmations disent combien de lignes partiront, comptées sur le serveur avant de demander, et passent par la protection de l’étiquette d’environnement. Elles n’apparaissent que là où le moteur le permet et où la session peut écrire.

MySQLMariaDBAurora

Avec MySQL, MariaDB et Aurora, les deux boutons sont disponibles.

PostgreSQL

Avec PostgreSQL, il n’y a que la remise à zéro des statistiques.

ClickHouse

Avec ClickHouse, les deux sont disponibles, et remettre les statistiques à zéro supprime aussi les exécutions, car c’est la même table.

SQL ServerOracle

Avec SQL Server et Oracle, aucun n’est proposé.

Mots-clés : vider, effacer, réinitialiser, statistiques, requêtes lentes, résumé