Tous les produits
Search
Centre de documentation

Hologres:Get and analyze slow query logs

Dernière mise à jour :Aug 11, 2026

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 ID par le nom d'utilisateur réel. Pour les utilisateurs RAM, utilisez p4_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

  1. Connectez-vous à la console HoloWeb.

  2. Dans la barre de navigation supérieure, cliquez sur Diagnostics and Optimization.

  3. Dans le volet de navigation de gauche, cliquez sur Historical Slow Query.

  4. 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.

  5. 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 digest pour 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_id pour 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 > 1 et SELECT * FROM t WHERE a > 2 produisent la même empreinte.

  • Le nombre d'éléments de tableau est ignoré : WHERE a IN (1, 2) et WHERE 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 t et SELECT * FROM public.t ont la même empreinte uniquement lorsque t se trouve dans le schéma public et 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 :

  1. Ajustez la plage temporelle dans la clause WHERE afin de couvrir la période durant laquelle l'utilisation du CPU ou de la mémoire était anormalement élevée. Par exemple, remplacez interval '10 min' par une plage correspondant à la fenêtre temporelle du pic d'activité.

  2. Ajoutez ORDER BY cpu_time_ms DESC pour trouver les requêtes intensives en CPU, ou ORDER BY memory_bytes DESC pour trouver celles qui consomment beaucoup de mémoire.

  3. Vérifiez les colonnes query_id, usename et query dans 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 -1 pour 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 -1 pour 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 -1 pour 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_log doit avoir accès à hg_query_log. Pour les exportations à l'échelle de l'instance, des permissions de superutilisateur ou pg_read_all_stats sont requises — sinon, les données exportées seront incomplètes.

  • query_start est 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_start dans 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

  1. 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);
  2. 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_cost intè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 pour get_next_cost peut 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 .