Lorsqu'une instance Hologres répond lentement ou que les requêtes prennent trop de temps, les journaux de requêtes lentes vous aident à identifier et diagnostiquer le problème. Cette rubrique explique comment interroger la table hologres.hg_query_log, interpréter les champs clés et utiliser le SQL de diagnostic pour cibler les problèmes de performance.
Guide des versions
| Version | Modification |
|---|---|
| V0.10 | Introduction des journaux de requêtes lentes. Les journaux pour les requêtes FAILED n'incluent pas les statistiques d'exécution (mémoire, lectures disque, volume de données lu, temps CPU ou query_stats). |
| V2.2 | Ajout de la colonne digest (empreinte SQL) à hg_query_log. |
| V2.2.7 | Modification de la valeur par défaut de log_min_duration_statement de 1 000 ms à 100 ms. |
| V3.0.2 | Ajout d'enregistrements agrégés pour les opérations DML et DQL s'exécutant en moins de 100 ms. Ajout également des champs calls et agg_stats. |
| V3.0.27 | Ajout de la prise en charge de la modification de la période de rétention des journaux via hg_query_log_retention_time_sec. |
Cette fonctionnalité nécessite Hologres V0.10 ou une version ultérieure. Pour vérifier la version de votre instance, accédez à la page des détails de l'instance dans la console Hologres. Pour mettre à niveau une instance antérieure, consultez Erreurs courantes de préparation à la mise à niveau ou contactez le support Hologres. Pour plus d'informations, consultez Comment obtenir plus de support en ligne ? .
Limitations
Les journaux de requêtes lentes sont conservés pendant un mois par défaut.
Une seule requête renvoie un maximum de 10 000 entrées de journal de requêtes lentes. Certains champs ont des limites de longueur — voir les description des champs dans la section relative à la table
hg_query_log.Les journaux de requêtes lentes font partie de l'entrepôt de métadonnées Hologres. Un échec de recherche dans les journaux de requêtes lentes n'affecte pas vos requêtes métier, et la disponibilité des journaux n'est pas couverte par l'accord de niveau de service (SLA) de Hologres.
Fonctionnement
Hologres stocke les journaux de requêtes lentes dans la table système hologres.hg_query_log. La table enregistre uniquement les instructions SQL terminées — les requêtes en cours d'exécution ne sont pas écrites dans la table. Ce comportement est cohérent sur les versions V2, V3 et ultérieures.
Éléments enregistrés :
Après la mise à niveau vers V0.10 : requêtes DML lentes s'exécutant pendant plus de 100 ms, et toutes les opérations DDL.
À partir de V3.0.2 : en plus des enregistrements détaillés pour les requêtes de plus de 100 ms, des enregistrements agrégés sont également écrits pour les requêtes DQL et DML se terminant en moins de 100 ms.
Fonctionnement de l'agrégation (V3.0.2+) :
Pour les requêtes rapides (moins de 100 ms), le système regroupe les requêtes DQL et DML réussies qui partagent la même empreinte SQL (digest). La clé d'agrégation est : server_addr, usename, datname, warehouse_id, application_name et digest. Chaque connexion vide un enregistrement agrégé par minute.
La table hg_query_log
La table contient deux types d'enregistrements, qui partagent le même schéma mais ont des sémantiques différentes :
| Champ | Type de données | Enregistrements détaillés (plus de 100 ms) | Enregistrements agrégés (moins de 100 ms) |
|---|---|---|---|
usename |
text | Nom d'utilisateur pour la requête. | Nom d'utilisateur pour la requête. |
status |
text | SUCCESS ou FAILED. |
Toujours SUCCESS (seules les requêtes réussies sont agrégées). |
query_id |
text | ID de requête unique. Une requête échouée a toujours un query_id ; une requête réussie peut ne pas en avoir. |
Le query_id de la première requête de la période d'agrégation avec la même clé d'agrégation. |
digest |
text | Empreinte SQL (hachage MD5). Ajouté dans V2.2. Pour plus d'informations, consultez Empreinte SQL. | Empreinte SQL. |
datname |
text | Nom de la base de données. | Nom de la base de données. |
command_tag |
text | Type de requête : DML (COPY, DELETE, INSERT, SELECT, UPDATE), DDL (ALTER TABLE, BEGIN, COMMENT, COMMIT, CREATE FOREIGN TABLE, CREATE TABLE, DROP FOREIGN TABLE, DROP TABLE, IMPORT FOREIGN SCHEMA, ROLLBACK, TRUNCATE TABLE) ou Other (CALL, CREATE EXTENSION, EXPLAIN, GRANT, SECURITY LABEL). | Le command_tag de la première requête de la période d'agrégation. |
warehouse_id |
integer | ID de l'entrepôt virtuel utilisé pour la requête. | L'ID de l'entrepôt virtuel de la première requête de la période d'agrégation. |
warehouse_name |
integer | Nom de l'entrepôt virtuel utilisé pour la requête. | Le nom de l'entrepôt virtuel de la première requête de la période d'agrégation. |
warehouse_cluster_id |
integer | Ajouté dans V3.0.2. L'ID du cluster au sein de l'entrepôt virtuel. Les ID de cluster commencent à 1. | L'ID du cluster de la première requête de la période d'agrégation. |
duration |
integer | Durée totale de la requête en millisecondes. Décomposée en trois étapes — voir ci-dessous. | Durée moyenne sur toutes les requêtes de la période d'agrégation. |
message |
text | Message d'erreur pour les requêtes ayant échoué. | Vide. |
query_start |
timestamptz | Heure de début de la requête. | Le query_start de la première requête de la période d'agrégation. |
query_date |
text | Date de début de la requête. | Le query_date de la première requête de la période d'agrégation. |
query |
text | Texte de la requête. Maximum 51 200 caractères ; les requêtes plus longues sont tronquées. | Le texte de la requête de la première requête de la période d'agrégation. |
result_rows |
bigint | Lignes renvoyées. Pour INSERT, le nombre de lignes insérées. | Valeur moyenne sur toutes les requêtes de la période d'agrégation. |
result_bytes |
bigint | Octets renvoyés. | Valeur moyenne. |
read_rows |
bigint | Lignes lues (non exact ; peut différer des lignes réellement analysées lorsqu'un index bitmap est utilisé). | Valeur moyenne. |
read_bytes |
bigint | Octets lus. | Valeur moyenne. |
affected_rows |
bigint | Lignes affectées par l'instruction DML. | Valeur moyenne. |
affected_bytes |
bigint | Octets affectés par l'instruction DML. | Valeur moyenne. |
memory_bytes |
bigint | Utilisation maximale cumulative de la mémoire sur tous les nœuds (non exact). Reflète la quantité de données lues par la requête. | Valeur moyenne. |
shuffle_bytes |
bigint | Octets brassés sur le réseau estimés (non exact). | Valeur moyenne. |
cpu_time_ms |
bigint | Temps CPU total en millisecondes sur toutes les tâches de calcul (non exact). Reflète la complexité de la requête. | Valeur moyenne. |
physical_reads |
bigint | Nombre de lots d'enregistrements lus depuis le disque. Reflète la fréquence des échecs de cache. | Valeur moyenne. |
pid |
integer | ID du processus du service de requête. | ID du processus de la première requête de la période d'agrégation. |
application_name |
text | Identifiant de l'application. Consultez valeurs application_name. | Type d'application. |
engine_type |
text[] | Moteur d'exécution utilisé. Consultez Types de moteur. | Le moteur de la première requête de la période d'agrégation. |
client_addr |
text | Adresse IP source (l'IP sortante de l'application, pas nécessairement l'IP réelle de l'application). | L'adresse source de la première requête de la période d'agrégation. |
table_write |
text | Table dans laquelle les données sont écrites. | La cible d'écriture de la première requête de la période d'agrégation. |
table_read |
text[] | Tables à partir desquelles les données sont lues. | Les sources de lecture de la première requête de la période d'agrégation. |
session_id |
text | ID de session. | L'ID de session de la première requête de la période d'agrégation. |
session_start |
timestamptz | Heure d'établissement de la connexion. | Heure de début de session pour toutes les requêtes de la période d'agrégation. |
command_id |
text | ID de commande ou d'instruction. | ID de commande pour toutes les requêtes de la période d'agrégation. |
optimization_cost |
integer | Temps nécessaire pour générer le plan d'exécution de la requête (ms). Des valeurs élevées indiquent une instruction SQL complexe. | Temps de génération du plan pour toutes les requêtes de la période d'agrégation. |
start_query_cost |
integer | Temps de démarrage de la requête (ms). Des valeurs élevées indiquent que la requête attend des verrous ou des ressources. | Temps de démarrage pour toutes les requêtes de la période d'agrégation. |
get_next_cost |
integer | Temps d'exécution de la requête (ms). Des valeurs élevées indiquent que le calcul est important et que l'exécution prend beaucoup de temps. | Temps d'exécution pour toutes les requêtes de la période d'agrégation. |
extended_cost |
text | Autres détails de synchronisation, y compris : build_dag (temps nécessaire pour construire le graphe acyclique dirigé (DAG) de calcul ; des valeurs élevées indiquent un accès lent aux métadonnées pour les tables externes), prepare_reqs (temps nécessaire pour préparer les requêtes pour le moteur d'exécution ; des valeurs élevées indiquent une résolution lente des adresses de shard) et champs spécifiques à Serverless (serverless_allocated_cores, serverless_allocated_workers, serverless_resource_used_time_ms). |
Coût étendu de la première requête de la période d'agrégation. |
plan |
text | Plan d'exécution de la requête. Maximum 102 400 caractères ; les plans plus longs sont tronqués. Contrôlé par log_min_duration_query_plan. |
Plan d'exécution de la première requête de la période d'agrégation. |
statistics |
text | Statistiques d'exécution de la requête. Maximum 102 400 caractères. Contrôlé par log_min_duration_query_stats. |
Statistiques d'exécution de la première requête de la période d'agrégation. |
visualization_info |
text | Données de visualisation du plan de requête. | Données de visualisation de la première requête de la période d'agrégation. |
query_detail |
text | Informations étendues sur la requête au format JSON. Maximum 10 240 caractères ; les valeurs plus longues sont tronquées. | Informations étendues de la première requête de la période d'agrégation. |
query_extinfo |
text[] | Informations étendues sur la requête au format tableau. Inclut serverless_computing pour les requêtes Serverless. À partir de V2.0.29, capture également l'ID AccessKey du compte. Remarque : l'ID AccessKey n'est pas enregistré pour les comptes locaux, les rôles liés au service (SLR) ou les connexions Security Token Service (STS). Pour les comptes temporaires, seul l'ID AccessKey temporaire est enregistré. |
Informations étendues de la première requête de la période d'agrégation. |
calls |
INT | Toujours 1 pour les enregistrements détaillés (pas d'agrégation). Ajouté dans V3.0.2. |
Nombre de requêtes avec la même clé d'agrégation dans la période d'agrégation. |
agg_stats |
JSONB | Vide. Ajouté dans V3.0.2. | Statistiques MIN, MAX et AVG pour les champs numériques (duration, memory_bytes, cpu_time_ms, physical_reads, optimization_cost, start_query_cost, get_next_cost). |
extended_info |
JSONB | Informations étendues sur Query Queue et Serverless Computing. Consultez valeurs extended_info. | Vide. |
Comprendre la décomposition de duration :
Le champ duration représente le temps total de la requête et est composé de trois étapes :
| Étape | Champ | Signification | Lorsque la valeur est élevée |
|---|---|---|---|
| Génération du plan | optimization_cost |
Temps nécessaire pour compiler le plan d'exécution | L'instruction SQL est complexe |
| Démarrage | start_query_cost |
Temps avant le début de l'exécution | Attente de verrous ou de ressources |
| Exécution | get_next_cost |
Temps nécessaire pour exécuter la requête | Le calcul est important et l'exécution prend beaucoup de temps |
Utilisez extended_cost pour obtenir des détails de synchronisation supplémentaires au-delà de ces trois étapes.
Valeurs application_name
| Source | Format |
|---|---|
| Realtime Compute for Apache Flink (VVR) | {client_version}_ververica-connector-hologres |
| Flink open source | {client_version}_hologres-connector-flink |
| Synchronisation de lecture hors ligne DataWorks | datax_{jobId} |
| Synchronisation d'écriture hors ligne DataWorks | {client_version}_datax_{jobId} |
| Synchronisation en temps réel DataWorks | {client_version}_streamx_{jobId} |
| HoloWeb | holoweb |
| Accès à la table externe MaxCompute | MaxCompute |
| Auto Analyze | AutoAnalyze |
| Quick BI | QuickBI_public_{version} |
| Planification DataWorks | {client_version}_dwscheduler_{tenant_id}_{scheduler_id}_{scheduler_task_id}_{bizdate}_{cyctime}_{scheduler_alisa_id} |
| Data Security Guard | dsg |
Pour les autres applications, définissez explicitement application_name dans la chaîne de connexion.
Types de moteur
| Moteur | Description |
|---|---|
| HQE | Moteur propriétaire natif de Hologres. La plupart des requêtes utilisent HQE pour une efficacité d'exécution élevée. |
| PQE | Le moteur PostgreSQL. Lorsque PQE apparaît, certains opérateurs SQL ne sont pas pris en charge nativement par HQE. La réécriture de ceux-ci comme décrit dans Optimiser les performances des requêtes peut améliorer les performances. |
| FixedQE | Le moteur d'exécution pour Fixed Plan. Gère efficacement le SQL de type service, tel que les lectures ponctuelles, les écritures ponctuelles et PrefixScan. Anciennement appelé SDK (renommé dans V2.2). Pour plus d'informations, consultez Accélérer l'exécution SQL avec Fixed Plan. |
| PG | Calcul local frontal pour les requêtes de métadonnées sur les tables système. Ne lit pas les données des tables utilisateur. Les instructions DDL utilisent également PG. |
Valeurs extended_info
Le champ extended_info enregistre la source de l'exécution Serverless Computing :
**Valeur de serverless_computing_source** |
Signification |
|---|---|
user_submit |
La requête a été soumise manuellement pour s'exécuter sur des ressources Serverless, indépendamment de Query Queue. |
query_queue |
Toutes les requêtes de la file d'attente de requêtes spécifiée s'exécutent sur des ressources Serverless. Consultez Utiliser des ressources Serverless Computing pour exécuter des requêtes dans une file d'attente de requêtes. |
query_queue_rerun |
La requête a été automatiquement réexécutée sur des ressources Serverless par la fonctionnalité de contrôle des grandes requêtes de Query Queue. Consultez Contrôle des grandes requêtes. |
Lorsque serverless_computing_source est query_queue_rerun, le champ query_id_of_triggered_rerun apparaît également, affichant l'ID de requête d'origine de l'instruction réexécutée.
Prérequis
Pour afficher les journaux de requêtes lentes, vous avez besoin de l'une des autorisations suivantes :
View logs for all databases in an instance:
-
Superuser : Exécutez la commande suivante. Remplacez
Alibaba Cloud account IDpar le nom d'utilisateur réel. Pour les utilisateurs RAM, utilisezp4_AccountID(ID du compte, pas le nom d'utilisateur RAM).ALTER USER "Alibaba Cloud account ID" SUPERUSER; -
Groupe pg_read_all_stats (pour les non-superutilisateurs) : Contactez un superutilisateur pour vous ajouter à ce groupe.
-- Standard PostgreSQL authorization GRANT pg_read_all_stats TO "Alibaba Cloud account ID"; -- Simple permission model (SPM) CALL spm_grant('pg_read_all_stats', 'Alibaba Cloud account ID'); -- Schema-level permission model (SLPM) CALL slpm_grant('pg_read_all_stats', 'Alibaba Cloud account ID');
View logs for the current database only:
Activez SPM ou SLPM et ajoutez l'utilisateur au rôle db_admin.
-- SPM
CALL spm_grant('<db_name>_admin', 'Alibaba Cloud account ID');
-- SLPM
CALL slpm_grant('<db_name>.admin', 'Alibaba Cloud account ID');
Les utilisateurs réguliers peuvent uniquement afficher leurs propres requêtes dans la base de données actuelle, sans configuration supplémentaire requise.
Afficher les journaux de requêtes lentes
Hologres propose deux méthodes pour afficher les journaux de requêtes lentes. Utilisez HoloWeb pour l'exploration visuelle — utilisez SQL pour les filtres personnalisés, les plages horaires et l'exportation.
| Méthode | Idéal pour | Contraintes |
|---|---|---|
| HoloWeb | Exploration visuelle et analyse des tendances | Superutilisateur uniquement ; 7 derniers jours uniquement |
SQL (table hg_query_log) |
Plages horaires personnalisées, filtrage et exportation | Nécessite des autorisations appropriées |
Afficher dans HoloWeb
Connectez-vous à la console HoloWeb.
Dans la barre de navigation supérieure, cliquez sur Diagnostics and Optimization.
Dans le volet de navigation de gauche, cliquez sur Historical Slow Query.
Définissez les conditions de requête en haut de la page Historical Slow Query. Pour une description des paramètres, consultez Requêtes lentes historiques.
-
Cliquez sur Search. Les résultats apparaissent dans deux zones :
Query Trend Analysis : affiche la fréquence des requêtes lentes et échouées au fil du temps, vous aidant à identifier les périodes problématiques.
Queries : répertorie les informations détaillées pour chaque requête lente ou échouée. Cliquez sur Customize Columns pour choisir les colonnes à afficher.
Interroger avec SQL
Interrogez directement la table hologres.hg_query_log pour une flexibilité totale. Consultez Diagnostiquer les requêtes pour des exemples SQL prêts à l'emploi.
Empreinte SQL
À partir de V2.2, la colonne digest dans hg_query_log stocke une empreinte SQL pour chaque requête. Pour SELECT, INSERT, DELETE et UPDATE, Hologres calcule un hachage MD5 comme empreinte.
Quand utiliser digest par rapport à query_id :
Utilisez
digestpour regrouper et analyser les requêtes du même type — par exemple, pour trouver quels modèles de requête consomment le plus de CPU en moyenne.Utilisez
query_idpour suivre une exécution de requête spécifique — par exemple, pour récupérer tous les détails d'une requête ayant échoué en particulier.
Calcul des empreintes :
Les empreintes sont collectées uniquement pour SELECT, INSERT, DELETE et UPDATE.
Les espaces blancs sont ignorés (espaces, sauts de ligne, tabulations).
Les valeurs constantes sont ignorées :
SELECT * FROM t WHERE a > 1etSELECT * FROM t WHERE a > 2produisent la même empreinte.Le nombre d'éléments de tableau est ignoré :
WHERE a IN (1, 2)etWHERE a IN (3, 4, 5)produisent la même empreinte.Pour INSERT avec des données constantes, l'empreinte n'est pas affectée par le nombre de lignes insérées.
La casse des lettres suit les règles de requête de Hologres.
L'empreinte inclut le nom de la base de données et le schéma entièrement qualifié, donc
SELECT * FROM tetSELECT * FROM public.tont la même empreinte uniquement lorsquetse trouve dans le schémapublicet que les deux requêtes référencent la même table.
Diagnostiquer les requêtes
Les exemples SQL suivants couvrent les scénarios de diagnostic les plus courants. Toutes les requêtes ciblent la table hologres.hg_query_log.
Compter toutes les requêtes dans le journal (par défaut : le dernier mois) :
SELECT count(*) FROM hologres.hg_query_log;
Exemple de sortie — 44 requêtes lentes au cours du dernier mois :
count
-------
44
(1 row)
Compter les requêtes lentes par utilisateur :
SELECT usename AS "User",
count(1) AS "Query count"
FROM hologres.hg_query_log
GROUP BY usename
ORDER BY count(1) DESC;
Exemple de sortie :
User | Query count
---------------------+-------------
1111111111111111 | 27
2222222222222222 | 11
3333333333333333 | 4
4444444444444444 | 2
(4 rows)
Rechercher une requête spécifique par ID :
SELECT * FROM hologres.hg_query_log WHERE query_id = '13001450118416xxxx';
Pour une description des champs renvoyés, consultez La table hg_query_log.
Trouver les requêtes gourmandes en ressources au cours des 10 dernières minutes :
Ajustez l'intervalle pour qu'il corresponde à votre fenêtre temporelle cible.
SELECT status AS "Status",
duration AS "Duration (ms)",
query_start AS "Start time",
(read_bytes / 1048576)::text || ' MB' AS "Data read",
(memory_bytes / 1048576)::text || ' MB' AS "Memory",
(shuffle_bytes / 1048576)::text || ' MB' AS "Shuffle",
(cpu_time_ms / 1000)::text || ' s' AS "CPU time",
physical_reads AS "Disk reads",
query_id AS "Query ID",
query::char(30)
FROM hologres.hg_query_log
WHERE query_start >= now() - interval '10 min'
ORDER BY duration DESC,
read_bytes DESC,
shuffle_bytes DESC,
memory_bytes DESC,
cpu_time_ms DESC,
physical_reads DESC
LIMIT 100;
Exemple de sortie :
Status | Duration (ms) | Start time | Data read | Memory | Shuffle | CPU time | Disk reads | Query ID | query
---------+---------------+------------------------+-----------+--------+---------+----------+------------+--------------------+--------------------------------
SUCCESS | 149 | 2021-03-30 23:45:01+08 | 0 MB | 25 MB | 454 MB | 321 s | 0 | 13001450118416xxxx | explain analyze SELECT * FROM
SUCCESS | 137 | 2021-03-30 23:49:18+08 | 247 MB | 21 MB | 213 MB | 803 s | 7771 | 13001491818416xxxx | explain analyze SELECT * FROM
FAILED | 53 | 2021-03-30 23:48:43+08 | 0 MB | 0 MB | 0 MB | 0 s | 0 | 13001484318416xxxx | SELECT ds::bigint / 0 FROM pub
(3 rows)
Scénario : Diagnostiquer une utilisation élevée du CPU ou de la mémoire après une mise à niveau de version d'instance
Cette requête est particulièrement utile lorsque l'utilisation du processeur ou de la mémoire augmente fortement après la mise à niveau de votre instance Hologres vers une nouvelle version. Pour identifier les requêtes à l'origine de cette consommation élevée de ressources :
Ajustez la plage temporelle dans la clause
WHEREafin de couvrir la période durant laquelle l'utilisation du CPU ou de la mémoire était anormalement élevée. Par exemple, remplacezinterval '10 min'par une plage correspondant à la fenêtre temporelle du pic d'activité.Ajoutez
ORDER BY cpu_time_ms DESCpour trouver les requêtes intensives en CPU, ouORDER BY memory_bytes DESCpour trouver celles qui consomment beaucoup de mémoire.Vérifiez les colonnes
query_id,usenameetquerydans les résultats pour identifier les requêtes spécifiques et leurs propriétaires, puis analysez et optimisez ces requêtes en conséquence.
Décomposer la durée par étape :
Utilisez cette méthode pour identifier quelle étape (optimization_cost, start_query_cost ou get_next_cost) représente la majeure partie du délai. Consultez le tableau de décomposition de la durée dans la section sur la table hg_query_log pour plus de détails sur chaque étape.
SELECT status AS "Status",
duration AS "Duration (ms)",
optimization_cost AS "Optimization cost (ms)",
start_query_cost AS "Startup cost (ms)",
get_next_cost AS "Execution cost (ms)",
duration - optimization_cost - start_query_cost - get_next_cost AS "Other cost (ms)",
query_id AS "Query ID",
query::char(30)
FROM hologres.hg_query_log
WHERE query_start >= now() - interval '10 min'
ORDER BY duration DESC,
start_query_cost DESC,
optimization_cost,
get_next_cost DESC,
duration - optimization_cost - start_query_cost - get_next_cost DESC
LIMIT 100;
Exemple de sortie :
Status | Duration (ms) | Optimization cost (ms) | Startup cost (ms) | Execution cost (ms) | Other cost (ms) | Query ID | query
---------+---------------+------------------------+-------------------+---------------------+-----------------+--------------------+--------------------------------
SUCCESS | 4572 | 521 | 320 | 3726 | 5 | 6000260625679xxxx | -- /* user: wang ip: xxx.xx.x
SUCCESS | 1490 | 538 | 98 | 846 | 8 | 12000250867886xxxx | -- /* user: lisa ip: xxx.xx.x
SUCCESS | 1230 | 502 | 95 | 625 | 8 | 26000512070295xxxx | -- /* user: zhang ip: xxx.xx.
(3 rows)
Afficher le volume de requêtes et les données lues par heure (3 dernières heures) :
SELECT date_trunc('hour', query_start) AS query_start,
count(1) AS query_count,
sum(read_bytes) AS read_bytes,
sum(cpu_time_ms) AS cpu_time_ms
FROM hologres.hg_query_log
WHERE query_start >= now() - interval '3 h'
GROUP BY 1;
Comparer le trafic avec la même fenêtre de la veille :
SELECT query_date,
count(1) AS query_count,
sum(read_bytes) AS read_bytes,
sum(cpu_time_ms) AS cpu_time_ms
FROM hologres.hg_query_log
WHERE query_start >= now() - interval '3 h'
GROUP BY query_date
UNION ALL
SELECT query_date,
count(1) AS query_count,
sum(read_bytes) AS read_bytes,
sum(cpu_time_ms) AS cpu_time_ms
FROM hologres.hg_query_log
WHERE query_start >= now() - interval '1d 3h'
AND query_start <= now() - interval '1d'
GROUP BY query_date;
Trouver la première requête ayant échoué dans une fenêtre temporelle :
SELECT status AS "Status",
regexp_replace(message, '\n', ' ')::char(150) AS "Error message",
duration AS "Duration (ms)",
query_start AS "Start time",
query_id AS "Query ID",
query::char(100) AS "Query"
FROM hologres.hg_query_log
WHERE query_start BETWEEN '2021-03-25 17:00:00'::timestamptz
AND '2021-03-25 17:42:00'::timestamptz + interval '2 min'
AND status = 'FAILED'
ORDER BY query_start ASC
LIMIT 100;
Exemple de sortie :
Status | Error message | Duration (ms) | Start time | Query ID | Query
--------+--------------------------------------------------------------+---------------+------------------------+--------------------+-------
FAILED | Query:[1070285448673xxxx] code: kActorInvokeError msg: "..." | 1460 | 2021-03-25 17:28:54+08 | 1070285448673xxxx | S...
FAILED | Query:[1016285560553xxxx] code: kActorInvokeError msg: "..." | 131 | 2021-03-25 17:28:55+08 | 1016285560553xxxx | S...
(2 rows)
Trouver les nouveaux motifs de requêtes de la veille (nombre total) :
Requêtes apparaissant pour la première fois par rapport à l'avant-veille, regroupées par empreinte digitale.
SELECT COUNT(1)
FROM (
SELECT DISTINCT t1.digest
FROM hologres.hg_query_log t1
WHERE t1.query_start >= CURRENT_DATE - INTERVAL '1 day'
AND t1.query_start < CURRENT_DATE
AND NOT EXISTS (
SELECT 1
FROM hologres.hg_query_log t2
WHERE t2.digest = t1.digest
AND t2.query_start < CURRENT_DATE - INTERVAL '1 day'
)
AND digest IS NOT NULL
) AS a;
Exemple de sortie — 10 nouveaux motifs de requêtes hier :
count
-------
10
(1 row)
Trouver les nouveaux motifs de requêtes de la veille (par type) :
SELECT a.command_tag,
COUNT(1)
FROM (
SELECT DISTINCT t1.digest, t1.command_tag
FROM hologres.hg_query_log t1
WHERE t1.query_start >= CURRENT_DATE - INTERVAL '1 day'
AND t1.query_start < CURRENT_DATE
AND NOT EXISTS (
SELECT 1
FROM hologres.hg_query_log t2
WHERE t2.digest = t1.digest
AND t2.query_start < CURRENT_DATE - INTERVAL '1 day'
)
AND t1.digest IS NOT NULL
) AS a
GROUP BY 1
ORDER BY 2 DESC;
Exemple de sortie :
command_tag | count
-------------+-------
INSERT | 8
SELECT | 2
(2 rows)
Trouver les nouveaux motifs de requêtes de la veille (avec détails) :
SELECT a.usename, a.status, a.query_id, a.digest,
a.datname, a.command_tag, a.query, a.cpu_time_ms, a.memory_bytes
FROM (
SELECT DISTINCT
t1.usename, t1.status, t1.query_id, t1.digest,
t1.datname, t1.command_tag, t1.query, t1.cpu_time_ms, t1.memory_bytes
FROM hologres.hg_query_log t1
WHERE t1.query_start >= CURRENT_DATE - INTERVAL '1 day'
AND t1.query_start < CURRENT_DATE
AND NOT EXISTS (
SELECT 1
FROM hologres.hg_query_log t2
WHERE t2.digest = t1.digest
AND t2.query_start < CURRENT_DATE - INTERVAL '1 day'
)
AND t1.digest IS NOT NULL
) AS a;
Trouver les nouveaux motifs de requêtes de la veille (par heure) :
SELECT to_char(a.query_start, 'HH24') AS query_start_hour,
a.command_tag,
COUNT(1)
FROM (
SELECT DISTINCT t1.query_start, t1.digest, t1.command_tag
FROM hologres.hg_query_log t1
WHERE t1.query_start >= CURRENT_DATE - INTERVAL '1 day'
AND t1.query_start < CURRENT_DATE
AND NOT EXISTS (
SELECT 1
FROM hologres.hg_query_log t2
WHERE t2.digest = t1.digest
AND t2.query_start < CURRENT_DATE - INTERVAL '1 day'
)
AND t1.digest IS NOT NULL
) AS a
GROUP BY 1, 2
ORDER BY 3 DESC;
Exemple de sortie — hier à 21h00, 8 motifs INSERT ; à 11h00 et 13h00, 1 motif SELECT chacun :
query_start_hour | command_tag | count
------------------+-------------+-------
21 | INSERT | 8
11 | SELECT | 1
13 | SELECT | 1
(3 rows)
Compter les requêtes lentes par empreinte digitale (hier) :
SELECT digest,
command_tag,
count(1)
FROM hologres.hg_query_log
WHERE query_start >= CURRENT_DATE - INTERVAL '1 day'
AND query_start < CURRENT_DATE
GROUP BY 1, 2
ORDER BY 3 DESC;
Trouver les 10 premiers motifs de requêtes avec le temps CPU moyen le plus élevé (dernier jour) :
SELECT digest,
avg(cpu_time_ms)
FROM hologres.hg_query_log
WHERE query_start >= CURRENT_DATE - INTERVAL '1 day'
AND query_start < CURRENT_DATE
AND digest IS NOT NULL
AND usename != 'system'
AND cpu_time_ms IS NOT NULL
GROUP BY 1
ORDER BY 2 DESC
LIMIT 10;
Trouver les 10 premiers motifs de requêtes avec l'utilisation moyenne de la mémoire la plus élevée (dernière semaine) :
SELECT digest,
avg(memory_bytes)
FROM hologres.hg_query_log
WHERE query_start >= CURRENT_DATE - INTERVAL '7 day'
AND query_start < CURRENT_DATE
AND digest IS NOT NULL
AND memory_bytes IS NOT NULL
GROUP BY 1
ORDER BY 2 DESC
LIMIT 10;
Paramètres de configuration
Utilisez ces paramètres GUC pour contrôler ce qui est journalisé et le niveau de détail capturé.
log_min_duration_statement
Contrôle la durée minimale de requête pour la journalisation.
Par défaut : 100 ms (à partir de la V2.2.7 ; les versions antérieures utilisent 1 000 ms par défaut).
Valeur minimale : 100 ms.
Définissez sur
-1pour désactiver complètement la journalisation des requêtes lentes.Seuls les superutilisateurs peuvent modifier ce paramètre au niveau de la base de données. Les utilisateurs réguliers peuvent le modifier au niveau de la session.
Les modifications s'appliquent uniquement aux nouvelles requêtes.
-- Database level (superuser only)
ALTER DATABASE dbname SET log_min_duration_statement = '250ms';
-- Session level
SET log_min_duration_statement = '250ms';
log_min_duration_query_stats
Contrôle si les statistiques d'exécution sont capturées pour une requête.
Par défaut : enregistre les statistiques pour les requêtes s'exécutant pendant plus de 10 s.
Définissez sur
-1pour désactiver la collecte de statistiques.Les statistiques utilisent un espace de stockage important. Abaissez cette valeur uniquement pour un dépannage ciblé ; rétablissez-la ensuite.
Les modifications s'appliquent uniquement aux nouvelles requêtes.
-- Database level (superuser only)
ALTER DATABASE dbname SET log_min_duration_query_stats = '20s';
-- Session level
SET log_min_duration_query_stats = '20s';
log_min_duration_query_plan
Contrôle si le plan d'exécution est capturé pour une requête.
Par défaut : enregistre les plans pour les requêtes s'exécutant pendant plus de 10 s.
Définissez sur
-1pour désactiver la capture du plan.Pour un dépannage ponctuel, utilisez plutôt
EXPLAIN— cela renvoie le plan instantanément sans journalisation.Les modifications s'appliquent uniquement aux nouvelles requêtes.
-- Database level (superuser only)
ALTER DATABASE dbname SET log_min_duration_query_plan = '10s';
-- Session level
SET log_min_duration_query_plan = '10s';
Modifier la rétention des journaux
À partir de la V3.0.27, vous pouvez modifier la durée de conservation des journaux de requêtes lentes au niveau de la base de données.
ALTER DATABASE <db_name> SET hg_query_log_retention_time_sec = 2592000;
| Aspect | Détail |
|---|---|
| Unité | Secondes |
| Plage | 3–30 jours (259 200–2 592 000 secondes) |
| Portée | Nouveaux journaux uniquement (les journaux existants conservent leur rétention d'origine) |
| S'applique à | Nouvelles connexions uniquement |
| Nettoyage | Les journaux expirés sont supprimés immédiatement, pas de manière asynchrone |
Exporter les journaux de requêtes lentes
Exportez les données de hg_query_log vers une table interne Hologres, une table externe MaxCompute ou OSS pour un stockage ou une analyse à long terme.
Avant d'exporter, notez :
Le compte exécutant la commande
INSERT INTO ... SELECT ... FROM hologres.hg_query_logdoit avoir accès àhg_query_log. Pour les exportations à l'échelle de l'instance, des permissions de superutilisateur oupg_read_all_statssont requises — sinon, les données exportées seront incomplètes.query_startest une colonne indexée. Incluez-la toujours dans votre clause WHERE pour améliorer les performances et réduire l'utilisation des ressources.-
N'appliquez pas de fonctions à
query_startdans la clause WHERE — cela empêcherait l'utilisation de l'index.-- Correct: use range conditions on query_start directly WHERE query_start >= '2022-08-03' AND query_start < '2022-08-04' -- Incorrect: wrapping query_start in a function bypasses the index WHERE to_char(query_start, 'yyyymmdd') = '20220101'
Exporter vers une table interne Hologres
-- Step 1: Create the target table
CREATE TABLE query_log_download (
usename text,
status text,
query_id text,
datname text,
command_tag text,
duration integer,
message text,
query_start timestamp with time zone,
query_date text,
query text,
result_rows bigint,
result_bytes bigint,
read_rows bigint,
read_bytes bigint,
affected_rows bigint,
affected_bytes bigint,
memory_bytes bigint,
shuffle_bytes bigint,
cpu_time_ms bigint,
physical_reads bigint,
pid integer,
application_name text,
engine_type text[],
client_addr text,
table_write text,
table_read text[],
session_id text,
session_start timestamp with time zone,
trans_id text,
command_id text,
optimization_cost integer,
start_query_cost integer,
get_next_cost integer,
extended_cost text,
plan text,
statistics text,
visualization_info text,
query_detail text,
query_extinfo text[]
);
-- Step 2: Export logs for a specific date
INSERT INTO query_log_download
SELECT
usename, status, query_id, datname, command_tag, duration, message,
query_start, query_date, query, result_rows, result_bytes, read_rows,
read_bytes, affected_rows, affected_bytes, memory_bytes, shuffle_bytes,
cpu_time_ms, physical_reads, pid, application_name, engine_type,
client_addr, table_write, table_read, session_id, session_start,
trans_id, command_id, optimization_cost, start_query_cost, get_next_cost,
extended_cost, plan, statistics, visualization_info, query_detail, query_extinfo
FROM hologres.hg_query_log
WHERE query_start >= '2022-08-03'
AND query_start < '2022-08-04';
Exporter vers une table externe MaxCompute
-
Dans MaxCompute, créez une table partitionnée pour recevoir les données :
CREATE TABLE IF NOT EXISTS mc_holo_query_log ( username STRING COMMENT 'The username for the query', status STRING COMMENT 'The final status of the query: success or failed', query_id STRING COMMENT 'The query ID', datname STRING COMMENT 'The name of the database for the query', command_tag STRING COMMENT 'The type of query', duration BIGINT COMMENT 'The query duration in milliseconds (ms)', message STRING COMMENT 'The error message', query STRING COMMENT 'The text content of the query', read_rows BIGINT COMMENT 'The number of rows read by the query', read_bytes BIGINT COMMENT 'The number of bytes read by the query', memory_bytes BIGINT COMMENT 'The peak memory consumption on a single node (not exact)', shuffle_bytes BIGINT COMMENT 'The estimated number of bytes for data shuffle (not exact)', cpu_time_ms BIGINT COMMENT 'The total CPU time in milliseconds (not exact)', physical_reads BIGINT COMMENT 'The number of physical reads', application_name STRING COMMENT 'The query application type', engine_type ARRAY<STRING> COMMENT 'The engine used for the query', table_write STRING COMMENT 'The table to which the SQL statement writes data', table_read ARRAY<STRING> COMMENT 'The table from which the SQL statement reads data', plan STRING COMMENT 'The execution plan for the query', optimization_cost BIGINT COMMENT 'The time to generate the query execution plan', start_query_cost BIGINT COMMENT 'The query startup time', get_next_cost BIGINT COMMENT 'The query execution duration', extended_cost STRING COMMENT 'Other detailed costs of the query', query_detail STRING COMMENT 'Other extended information about the query (JSON format)', query_extinfo ARRAY<STRING> COMMENT 'Other extended information about the query (ARRAY format)', query_start STRING COMMENT 'The query start time', query_date STRING COMMENT 'The query start date' ) COMMENT 'Hologres instance query log' PARTITIONED BY (ds STRING COMMENT 'stat date') LIFECYCLE 365; ALTER TABLE mc_holo_query_log ADD PARTITION (ds=20220803); -
Dans Hologres, importez la table MaxCompute en tant que table externe et exportez les journaux :
IMPORT FOREIGN SCHEMA project_name LIMIT TO (mc_holo_query_log) FROM SERVER odps_server INTO public; INSERT INTO mc_holo_query_log SELECT usename AS username, status, query_id, datname, command_tag, duration, message, query, read_rows, read_bytes, memory_bytes, shuffle_bytes, cpu_time_ms, physical_reads, application_name, engine_type, table_write, table_read, plan, optimization_cost, start_query_cost, get_next_cost, extended_cost, query_detail, query_extinfo, query_start, query_date, '20220803' FROM hologres.hg_query_log WHERE query_start >= '2022-08-03' AND query_start < '2022-08-04';
FAQ
Les métriques « rows returned » et « rows read » sont absentes dans Hologres V1.1.
Ce phénomène s'explique par une collecte incomplète des journaux de requêtes lentes dans certaines versions de la V1.1. Pour les versions V1.1.36 à V1.1.49, activez le paramètre GUC suivant afin de collecter l'intégralité des statistiques :
-- Database level (recommended — set once per database)
ALTER DATABASE <db_name> SET hg_experimental_force_sync_collect_execution_statistics = ON;
-- Session level
SET hg_experimental_force_sync_collect_execution_statistics = ON;
Remplacez <db_name> par le nom de votre base de données.
Si votre instance est antérieure à la version V1.1.36, consultez la rubrique Common upgrade preparation errors ou contactez le support Hologres. Pour plus d'informations, reportez-vous à la section How do I get more online support? .
Ce comportement est corrigé par défaut à partir de la version V1.1.49.
La durée indiquée dans les journaux de requêtes lentes inclut-elle le temps de récupération (Fetching) ?
Non. Le champ duration des journaux de requêtes lentes de Hologres mesure uniquement le temps d'exécution côté serveur, qui comprend la génération du plan (optimization_cost), le démarrage (start_query_cost) et le calcul (get_next_cost). Il n'inclut pas le temps passé par le client à récupérer les données de résultat (phase de Fetching).
Si les requêtes exécutées depuis un outil BI tel que Quick BI prennent significativement plus de temps que la même instruction SQL lancée via HoloWeb ou en ligne de commande, les causes fréquentes sont les suivantes :
L'outil BI envoie plusieurs requêtes simultanément, ce qui augmente le temps de réponse global en cas de parallélisme élevé.
Le champ
get_next_costintègre le temps de transfert réseau nécessaire à l'envoi des données de résultat du serveur vers le client. Une valeur élevée pourget_next_costpeut refléter une latence de récupération des données côté client plutôt qu'une lenteur de calcul côté serveur.
Pour distinguer les délais imputables au serveur de ceux liés au client, exécutez la requête avec EXPLAIN ANALYZE et examinez le champ get_next_cost . Une valeur get_next_cost élevée, associée à des valeurs faibles pour optimization_cost et start_query_cost , indique généralement que le temps est consacré au transfert des données plutôt qu'à l'exécution de la requête.
Étapes suivantes
Pour surveiller et gérer les requêtes actives sur votre instance, consultez la rubrique Manage queries .