Hologres インスタンスの応答が遅い、またはクエリに時間がかかりすぎる場合は、スロークエリログを表示および分析して問題を迅速に特定します。このプロセスは、低速または失敗したクエリを特定、診断、分析するのに役立ち、システムを最適化してパフォーマンスを向上させることができます。このトピックでは、Hologres でスロークエリログを表示および分析する方法について説明します。
バージョンガイド
|
Hologres バージョン |
機能 |
説明 |
|
V0.10 |
スロークエリログの表示と分析機能を追加しました。 |
|
|
V2.2.7 |
log_min_duration_statement パラメーターのデフォルト値を最適化しました。 |
スロークエリログには、すべての DDL ステートメント、すべての失敗した SQL ステートメント、および Hologres V2.2.7 以降、 |
制限事項
Hologres でスロークエリログをクエリする際には、次の制限が適用されます:
-
スロークエリログはデフォルトで 1 か月間保持されます。その月内の任意の期間のデータをクエリできます。
-
システムの安定性を確保し、トラフィックの過負荷を防ぐため、1 回のクエリで最大 10,000 件のスロークエリログを返すことができます。スロークエリログの一部のフィールドには長さの制限があります。詳細については、
query_logテーブルのフィールド説明をご参照ください。 -
スロークエリログは Hologres メタデータウェアハウスの一部です。スロークエリログの検索が失敗しても、インスタンス内のビジネスクエリには影響しません。したがって、スロークエリログの安定性は、製品のサービスレベルアグリーメント (SLA) の対象外です。
query_log テーブルの表示
Hologres は、スロークエリログを hologres.hg_query_log システムテーブルに保存します。hg_query_log テーブルには、完了した SQL ステートメントのみが記録されます。まだ実行中のクエリは、このテーブルには書き込まれません。この動作は、Hologres V2、V3、およびそれ以降のバージョンで一貫しています。さらに:
-
インスタンスを V0.10 にアップグレードすると、Hologres はデフォルトで 100 ms を超えて実行される低速な DML クエリとすべての DDL 操作のログを収集します。
-
V3.0.2 以降、Hologres は hologres.hg_query_log テーブルで 100 ms 未満で実行される DML およびクエリ操作の集計レコードをサポートします。
-
システムは、指紋を持ち、100 ms 未満で実行される成功した DQL および DML クエリのレコードを集計します。
-
集計の主な列は、server_addr、usename、datname、warehouse_id、application_name、および digest です。
-
各接続は、1 分に 1 回データを要約して報告します。
-
次の表は、hologres.hg_query_log システムテーブルのフィールドについて説明しています。
|
フィールド |
データ型 |
詳細な DML および DQL レコード (100 ms 超) の説明 |
集計された DML および DQL レコード (100 ms 未満) の説明 |
|
usename |
text |
クエリのユーザー名。 |
クエリのユーザー名。 |
|
status |
text |
クエリの最終ステータスは success または failure です。
|
クエリの最終ステータス。値は SUCCESS です。集計データには成功したレコードのみが含まれます。 |
|
query_id |
text |
クエリの ID。この ID は一意です。 失敗したクエリには常に query_id がありますが、成功したクエリにはない場合があります。 |
集計期間内に同じプライマリ集計キーを持つ最初のクエリのクエリ ID。 |
|
digest |
text |
SQL 指紋コード。 SELECT、INSERT、DELETE、UPDATE クエリの場合、システムは SQL 指紋として MD5 ハッシュ値を計算します。SQL 指紋の収集と計算のルールに関する詳細については、「SQL 指紋」をご参照ください。 説明
Hologres V2.2 以降、digest 列が追加され、SQL 指紋コードが表示されるようになりました。インスタンスが V2.1 以前の場合は、Hologres テクニカルサポートに連絡してインスタンスをアップグレードしてください。 |
SQL 指紋コード。 |
|
datname |
text |
クエリのデータベース名。 |
クエリのデータベース名。 |
|
command_tag |
text |
クエリのタイプ。 含まれるもの:
|
集計期間内に同じプライマリ集計キーを持つ最初のクエリのクエリタイプ。 |
|
warehouse_id |
integer |
クエリに使用される仮想ウェアハウスの ID。 |
集計期間内に同じ集計プライマリキーを持つ最初のクエリの計算グループ ID。 |
|
warehouse_name |
integer |
クエリに使用される仮想ウェアハウスの名前。 |
集計期間内に、同じ集計プライマリキーを共有する最初のクエリの計算グループの名前。 |
|
warehouse_cluster_id |
integer |
このフィールドは Hologres V3.0.2 で追加されました。クエリに使用される仮想ウェアハウス内のクラスター ID です。各仮想ウェアハウスのクラスター ID は 1 から始まります。 |
集計期間内に同じプライマリ集計キーを持つ最初のクエリのクラスター ID。 |
|
duration |
integer |
クエリ期間 (ミリ秒、ms)。
デフォルトでは、システムは 1 秒より長く実行される DML ステートメントとすべての DDL ステートメントのみを表示します。GUC パラメーター |
集計期間内に同じプライマリ集計キーを持つすべてのクエリの平均クエリ期間。 |
|
message |
text |
エラーメッセージ。 |
空。 |
|
query_start |
timestamptz |
クエリの開始時刻。 |
集計期間内に同じプライマリ集計キーを持つ最初のクエリのクエリ開始時刻。 |
|
query_date |
text |
クエリの開始日。 |
集計期間内に同じプライマリ集計キーを持つ最初のクエリのクエリ開始日。 |
|
query |
text |
クエリのテキストコンテンツ。 クエリの最大長は 51,200 文字です。長いクエリは切り捨てられる場合があります。 |
集計期間内に同じプライマリ集計キーを持つ最初のクエリのテキストコンテンツ。 |
|
result_rows |
bigint |
返された行数。 INSERT コマンドの場合、これは挿入された行数です。 |
集計期間内に同じプライマリ集計キーを持つすべてのクエリの result_rows の平均値。 |
|
result_bytes |
bigint |
返されたバイト数。 |
集計期間内に同じプライマリ集計キーを持つすべてのクエリの result_bytes の平均値。 |
|
read_rows |
bigint |
読み取られたデータ行数。 これは正確な値ではありません。ビットマップインデックスが使用されている場合、この値は実際にスキャンされた行数と異なる場合があります。 |
集計期間内に同じプライマリ集計キーを持つすべてのクエリの read_rows の平均値。 |
|
read_bytes |
bigint |
読み取られたバイト数。 |
集計期間内に同じプライマリ集計キーを持つすべてのクエリの read_bytes の平均値。 |
|
affected_rows |
bigint |
DML ステートメントによって影響を受けた行数。 |
集計期間内に同じプライマリ集計キーを持つすべてのクエリの affected_rows の平均値。 |
|
affected_bytes |
bigint |
DML ステートメントによって影響を受けたバイト数。 |
集計期間内に同じプライマリ集計キーを持つすべてのクエリの affected_bytes の平均値。 |
|
memory_bytes |
bigint |
各ノードでの累積ピークメモリ使用量 (正確ではありません)。 これは、クエリが実行されたすべてのノードでのピークメモリ使用量の合計を表します。クエリによって読み取られたデータ量を大まかに反映します。 |
集計期間内に同じプライマリ集計キーを持つすべてのクエリの memory_bytes の平均値。 |
|
shuffle_bytes |
bigint |
データシャッフルの推定バイト数 (正確ではありません)。 これは、ネットワーク経由で転送されたデータ量を大まかに反映します。 |
集計期間内に同じプライマリ集計キーを持つすべてのクエリの shuffle_bytes の平均値。 |
|
cpu_time_ms |
bigint |
合計 CPU 時間 (ミリ秒、ms) (正確ではありません)。 これは、すべての計算タスクによって消費された CPU 時間を反映します。複数の CPU コアからの計算時間の合計であり、複雑さを大まかに示します。 |
集計期間内に同じプライマリ集計キーを持つすべてのクエリの cpu_time_ms の平均値。 |
|
physical_reads |
bigint |
物理読み取りの回数。 これは、レコードバッチがディスクから読み取られた回数を反映します。メモリキャッシュミスの回数を大まかに示します。 |
集計期間内に同じプライマリ集計キーを持つすべてのクエリの physical_reads の平均値。 |
|
pid |
integer |
サービスのプロセス ID をクエリします。 |
集計期間内に同じプライマリ集計キーを持つ最初のクエリのクエリサービスプロセス ID。 |
|
application_name |
text |
アプリケーションタイプをクエリできます。 一般的なアプリケーションタイプには、以下が含まれます:
他のアプリケーションについては、Hologres に接続する際に接続文字列で |
クエリのアプリケーションタイプ。 |
|
engine_type |
text[] |
クエリに使用されるエンジン。 エンジンタイプには、以下が含まれます:
|
集計期間内に同じプライマリ集計キーを持つ最初のクエリに使用されるエンジン。 |
|
client_addr |
text |
クエリのソースアドレス。 これはアプリケーションの出力 IP アドレスを表し、必ずしも実際のアプリケーション IP アドレスではありません。 |
集計期間内に同じプライマリ集計キーを持つ最初のクエリのソースアドレス。 |
|
table_write |
text |
SQL ステートメントがデータを書き込むテーブル。 |
集計期間内に同じプライマリ集計キーを持つ最初のクエリがデータを書き込むテーブル。 |
|
table_read |
text[] |
SQL ステートメントがデータを読み取るテーブル。 |
集計期間内に同じプライマリ集計キーを持つ最初のクエリがデータを読み取るテーブル。 |
|
session_id |
text |
セッション ID。 |
集計期間内に同じプライマリ集計キーを持つ最初のクエリのセッション ID。 |
|
session_start |
timestamptz |
セッションの開始時刻。 これは接続が確立された時刻を表します。 |
集計期間内に同じプライマリ集計キーを持つすべてのクエリのセッション開始時刻。 |
|
command_id |
text |
コマンドまたはステートメント ID。 |
集計期間内に同じプライマリ集計キーを持つすべてのクエリのコマンドまたはステートメント ID。 |
|
optimization_cost |
integer |
クエリ実行計画を生成するための時間。 コストが高い場合は、通常、SQL ステートメントが複雑であることを意味します。 |
集計期間内に同じプライマリ集計キーを持つすべてのクエリの実行計画を生成するための時間。 |
|
start_query_cost |
integer |
クエリの起動時間。 コストが高い場合は、通常、クエリがロックまたはリソースを待機していることを意味します。 |
集計期間内に同じプライマリ集計キーを持つすべてのクエリのクエリ起動時間。 |
|
get_next_cost |
integer |
クエリの実行期間。 コストが高い場合は、通常、計算量が大きく、実行に時間がかかることを意味します。ビジネスニーズに基づいて SQL ステートメントを最適化できます。 |
集計期間内に同じプライマリ集計キーを持つすべてのクエリのクエリ実行期間。 |
|
extended_cost |
text |
その他の詳細なクエリタイミング情報。
|
集計期間内に同じプライマリ集計キーを持つ最初のクエリのその他の詳細なコスト。 |
|
plan |
text |
クエリの実行計画。 実行計画の最大長は 102,400 文字です。長い計画は切り捨てられる場合があります。GUC パラメーター |
集計期間内に同じプライマリ集計キーを持つ最初のクエリの実行計画。 |
|
statistics |
text |
クエリの実行統計。 統計情報の最大長は 102,400 文字です。長い情報は切り捨てられる場合があります。GUC パラメーター |
集計期間内に同じプライマリ集計キーを持つ最初のクエリの実行統計。 |
|
visualization_info |
text |
クエリ計画の可視化情報。 |
集計期間内に同じプライマリ集計キーを持つ最初のクエリのクエリ計画可視化情報。 |
|
query_detail |
text |
クエリに関するその他の拡張情報 (JSON 形式で保存)。 説明
拡張情報の最大長は 10,240 文字です。長い情報は切り捨てられる場合があります。 |
集計期間内に同じプライマリ集計キーを持つ最初のクエリに関するその他の拡張情報。 |
|
query_extinfo |
text[] |
説明
ローカルアカウント、サービスリンクロール (SLR)、またはセキュリティトークンサービス (STS) でのログインでは、AccessKey ID は記録されません。一時的なアカウントでログインした場合、一時的な AccessKey ID のみが記録されます。 |
集計期間内に同じプライマリ集計キーを持つ最初のクエリに関するその他の拡張情報。 |
|
calls |
INT |
詳細レコードには集計動作がないため、値は 1 です。 |
集計期間内に同じプライマリ集計キーを持つクエリの数。 |
|
agg_stats |
JSONB |
空。 |
集計期間内に同じプライマリ集計キーを持つクエリの duration、memory_bytes、cpu_time_ms、physical_reads、optimization_cost、start_query_cost、get_next_cost などの数値フィールドの MIN、MAX、AVG などの統計値を記録します。 |
|
extended_info |
JSONB |
その他の拡張情報。クエリキューやサーバーレスコンピューティングなどの拡張情報を記録します。
|
空。 |
calls および agg_stats フィールドは V3.0.2 で追加されました。
権限の付与
スロークエリログを表示するには、特定の権限が必要です。権限ルールと権限付与方法は次のとおりです:
-
インスタンス内のすべてのデータベースのスロークエリログを表示する。
-
ユーザーにスーパーユーザー権限を付与する。
スーパーユーザーアカウントは、インスタンス内のすべてのデータベースのすべてのスロークエリログを表示できます。ユーザーにスーパーユーザー権限を付与すると、ユーザーはこれらのログを表示できるようになります。権限を付与する際、「Alibaba Cloud アカウント ID」を実際のユーザー名に置き換えてください。RAM ユーザーを使用する場合は、Alibaba Cloud アカウント ID を「p4_AccountID」に置き換えてください。注意:これはアカウント ID であり、RAM ユーザーの名前ではありません。アカウント ID はアカウントページで確認できます。
ALTER USER "Alibaba Cloud account ID" SUPERUSER; -
ユーザーを pg_read_all_stats ユーザーグループに追加する。
スーパーユーザーに加えて、Hologres は pg_read_all_stats グループのユーザーがすべてのデータベースのスロークエリログを表示することも許可します。一般ユーザーがすべてのログを表示する必要がある場合は、スーパーユーザーに連絡してこのグループに追加してもらうことができます。権限付与コマンドは次のとおりです:
GRANT pg_read_all_stats TO "Alibaba Cloud account ID";-- 標準権限モデルで権限を付与 CALL spm_grant('pg_read_all_stats', 'Alibaba Cloud account ID'); -- 簡易権限モデルで権限を付与 CALL slpm_grant('pg_read_all_stats', 'Alibaba Cloud account ID'); -- スキーマレベルの簡易権限モデルで権限を付与
-
-
現在のデータベースのスロークエリログを表示する。
簡易権限モデル (SPM) またはスキーマレベルの簡易権限モデル (SLPM) を有効にし、ユーザーを db_admin ユーザーグループに追加します。db_admin ロールは、現在のデータベースのクエリログを表示できます。
CALL spm_grant('<db_name>_admin', 'Alibaba Cloud account ID'); -- 簡易権限モデルで権限を付与 CALL slpm_grant('<db_name>.admin', 'Alibaba Cloud account ID'); -- スキーマレベルの簡易権限モデルで権限を付与 -
一般ユーザーは、現在のデータベースで自身が実行したクエリのスロークエリログのみをクエリできます。
HoloWeb でのスロークエリの表示
HoloWeb を使用してスロークエリログを表示できます。
-
HoloWeb は現在、最大 7 日間の過去のスロークエリログの表示をサポートしています。
-
この情報を表示できるのはスーパーユーザーアカウントのみです。一般の権限を持つアカウントは SQL コマンドを使用する必要があります。
-
HoloWeb コンソールにログインします。詳細については、「HoloWeb への接続とクエリの実行」をご参照ください。
-
上部のナビゲーションバーで、Diagnostics and Optimization をクリックします。
-
左側のナビゲーションウィンドウで、Historical Slow Query をクリックします。
-
Historical Slow Query ページの上部で、クエリ条件を編集します。
パラメーターの説明については、「過去のスロークエリ」をご参照ください。
-
Search をクリックします。結果は Query Trend Analysis および Queries エリアに表示されます。
-
Query Trend Analysis
クエリ傾向分析には、低速および失敗したクエリの最近の傾向が表示されます。スロークエリの頻度が高い期間を監視して、問題をより適切に特定し、解決することができます。
-
Queries
クエリリストには、低速および失敗したクエリの詳細情報が表示されます。パラメーターの説明については、「過去のスロークエリ」をご参照ください。また、Customize Columns をクリックして、クエリリストに表示する列を選択することもできます。
-
SQL 指紋
Hologres V2.2 以降、スロークエリログを保存する hologres.hg_query_log システムテーブルには、SQL 指紋を表示するための digest 列が含まれています。SELECT、INSERT、DELETE、UPDATE クエリの場合、システムは SQL 指紋として MD5 ハッシュ値を計算します。これにより、クエリを分類および分析するのに役立ちます。
SQL 指紋の収集と計算のルールは次のとおりです:
-
デフォルトでは、指紋は SELECT、INSERT、DELETE、UPDATE クエリに対してのみ収集されます。
-
定数としてデータを挿入する
INSERTステートメントの場合、SQL 指紋は挿入されるデータの量に影響されません。 -
SQL 指紋を計算する際、SQL ステートメントの大文字と小文字の扱いは、Hologres のクエリにおける大文字と小文字のルールと一致します。
-
計算では、スペース、改行、タブ文字など、クエリ内のすべての空白文字が無視されます。SQL ステートメントの構造情報のみが考慮されます。
-
計算では、クエリ内の特定の定数値が指紋に与える影響は無視されます。
例:クエリ
SELECT * FROM t WHERE a > 1;とSELECT * FROM t WHERE a > 2;は同じ SQL 指紋を持ちます。 -
クエリ内の配列定数については、計算は配列内の要素数に影響されません。
例:クエリ
SELECT * FROM t WHERE a IN (1, 2);とSELECT * FROM t WHERE a IN (3, 4, 5);は同じ SQL 指紋を持ちます。 -
計算では、データベース名が考慮され、各テーブルのスキーマプロパティが自動的に補完されます。テーブル名とそのプロパティの両方を使用して、異なるクエリのテーブルを区別します。
例:クエリ
SELECT * FROM t;とSELECT * FROM public.t;の SQL 指紋が同じになるのは、テーブルtがpublicスキーマにあり、両方のクエリが同じテーブルを参照している場合のみです。
クエリ診断
hologres.hg_query_log テーブルをクエリして、スロークエリログを取得できます。以下のセクションでは、クエリログを診断するための一般的な SQL ステートメントを提供します:
-
query_log 内のクエリの総数をクエリします (デフォルトは過去 1 か月間のデータ)。
SELECT count(*) FROM hologres.hg_query_log;次の結果は、過去 1 か月間に指定されたしきい値を超える期間で 44 のクエリが実行されたことを示します。
count ------- 44 (1 row) -
各ユーザーのスロークエリ数をクエリします。
SELECT usename AS "User", count(1) as "Query Count" FROM hologres.hg_query_log GROUP BY usename order by count(1) desc;次の結果が返されます。
count(1)の単位はクエリ数です。User | Query Count -----------------------+----- 1111111111111111 | 27 2222222222222222 | 11 3333333333333333 | 4 4444444444444444 | 2 (4 rows) -
特定のスロークエリの詳細をクエリします。
SELECT * FROM hologres.hg_query_log WHERE query_id = '13001450118416xxxx';次の結果が返されます。パラメーターの詳細については、「query_log テーブル」をご参照ください。
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 | command_id | optimization_cost | start_query_cost | get_next_cost | extended_cost | plan | statistics | visualization_info | query_detail | query_extinfo -----------------------+---------+--------------------+---------+-------------+----------+---------+------------------------+------------+---------------------------------------------------------------------------------------------------------+-------------+--------------+-----------+------------+---------------+----------------+--------------+---------------+-------------+----------------+---------+------------------+-------------+---------------+-------------+------------+-----------------+------------------------+------------+-------------------+------------------+---------------+---------------+------+------------+--------------------+--------------+--------------- p4_11111111111xxxx | SUCCESS | 13001450118416xxxx | dbname | SELECT | 149 | | 2021-03-30 23:45:01+08 | 20210330 | explain analyze SELECT * FROM tablename WHERE user_id = '20210330010xxxx' limit 1000; | 1000 | 417172 | 0 | 0 | -1 | -1 | 26731376 | 476603616 | 321626 | 0 | 1984913 | psql | {HQE} | 33.41.xxx.xxx | | | 6063475a.1e4991 | 2021-03-30 23:44:26+08 | 0 | 58 | 22 | 67 | | | | | | (1 row) -
最近の期間 (たとえば過去 10 分間) の高消費クエリをクエリします。必要に応じて、特定の期間の高消費クエリをクエリするために期間を変更することもできます。
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 "QueryID", 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;次の結果が返されます:
Status |Duration (ms) | Start Time | Data Read | Memory| Shuffle | CPU Time | Disk Reads | QueryID | 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) -
昨日の新規クエリ数を表示します。
-
昨日の新規クエリの総数をカウントします。
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;次の結果は、昨日合計 10 件の新規クエリが追加されたことを示します。
count ------- 10 (1 row) -
クエリタイプ (command_tag) 別に昨日の新規クエリ数をグループ化してカウントします。
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;次の結果は、昨日 8 件の新規
INSERTクエリと 2 件の新規SELECTクエリが追加されたことを示します。command_tag | count ------------+-------- INSERT | 8 SELECT | 2 (2 rows)
-
-
昨日の新規クエリの詳細を表示します。
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;次の結果が返されます:
usename |status |query_id |digest |datname|command_tag |query |cpu_time_ms |memory_bytes -----------------+--------+--------------------+------------------------------------+-------+-------------+-----------------------------------+--------------+-------------- 111111111111xxxx |SUCCESS |100100425827776xxxx |md58cf93d91c36c6bc9998add971458ba1a |dbname |INSERT |INSERT INTO xxx SELECT * FROM xxx | 1748| 898808596 111111111111xxxx |SUCCESS |100100425827965xxxx |md5f7e87e2c9e0b3d9eddcd6b3bc7f04b3b |dbname |INSERT |INSERT INTO xxx SELECT * FROM xxx | 59891| 6819529886 111111111111xxxx |SUCCESS |100100425829654xxxx |md55612dc09d2d81074fd5deed1aa3eca9b |dbname |INSERT |INSERT INTO xxx SELECT * FROM xxx | 3| 2100039 111111111111xxxx |SUCCESS |100100425829664xxxx |md58d3bf67fbdf2247559bc916586d40011 |dbname |INSERT |INSERT INTO xxx SELECT * FROM xxx | 10729| 2052861937 111111111111xxxx |SUCCESS |100100425830099xxxx |md503bd45d6b2d7701c2617d079b4d55a10 |dbname |INSERT |INSERT INTO xxx SELECT * FROM xxx | 2196| 897948034 111111111111xxxx |SUCCESS |100100425830186xxxx |md5c62169eaf3ea3a0c59bdc834a8141ac4 |dbname |INSERT |INSERT INTO xxx SELECT * FROM xxx | 5268| 1734305972 111111111111xxxx |SUCCESS |100100425830448xxxx |md59aa0c73b24c9c9eba0b34c8fdfc23bb0 |dbname |INSERT |INSERT INTO xxx SELECT * FROM xxx | 2| 2098402 111111111111xxxx |SUCCESS |100100425830459xxxx |md57d22c1d37b68984e9472f11a4c9fd04e |dbname |INSERT |INSERT INTO xxx SELECT * FROM xxx | 113| 76201984 111111111111xxxx |SUCCESS |100100525468694xxxx |md5ac7d6556fae123e9ea9527d8f1c94b1c |dbname |SELECT |SELECT * FROM xxx limit 200 | 6| 1048576 111111111111xxxx |SUCCESS |100101025538840xxxx |md547d09cdad4d5b5da74abaf08cba79ca0 |dbname |SELECT |SELECT * FROM xxx limit 200 |\N |\N (10 rows) -
昨日の新規クエリの傾向を表示します (時間別に表示)。
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;次の結果は、昨日の 11:00、13:00、21:00 にそれぞれ 1 件の SELECT、1 件の SELECT、8 件の INSERT クエリが追加されたことを示します。
query_start_hour |command_tag |count ------------------+-------------+----- 21 |INSERT | 8 11 |SELECT | 1 13 |SELECT | 1 (3 rows) -
分類されたスロークエリの数。
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; -
過去 1 日間で平均 CPU 時間が最も高い上位 10 件のクエリをクエリします。
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; -
過去 1 週間で平均メモリ消費量 (memory_bytes) が最も高い上位 10 件のクエリを表示します。
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; -
過去 3 時間の 1 時間あたりのクエリ量と合計データ読み取り量を表示して、データ量の変化を確認します。
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; -
過去 3 時間のデータアクセス量を昨日の同時刻と比較して、データアクセス量の変化を確認します。
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; -
最近の期間 (たとえば過去 10 分間) の各ステージで実行時間が長いクエリをクエリします。必要に応じて、特定の期間の各ステージで実行時間が長いクエリをクエリするために期間を変更することもできます。
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 "QueryID", 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;次の結果が返されます:
Status | Duration (ms) | Optimization Cost (ms) | Startup Cost (ms) | Execution Cost (ms) | Other Cost (ms) | QueryID | 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) -
最初に失敗したクエリをクエリします。
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 "QueryID", 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;次の結果が返されます:
Status | Error Message | Duration (ms) | Start Time | QueryID | Query --------+--------------------------------------------------------------------------------------------------------------------------------------------------------+-------+------------------------+-------------------+------- FAILED | Query:[1070285448673xxxx] code: kActorInvokeError msg: "[holo_query_executor.cc:330 operator()] HGERR_code XX000 HGERR_msge internal error: status { c | 1460 | 2021-03-25 17:28:54+08 | 1070285448673xxxx | S... FAILED | Query:[1016285560553xxxx] code: kActorInvokeError msg: "[holo_query_executor.cc:330 operator()] HGERR_code XX000 HGERR_msge internal error: status { c | 131 | 2021-03-25 17:28:55+08 | 1016285560553xxxx | S... (2 rows)
スロークエリログのライフサイクルの変更
Hologres V3.0.27 以降、スロークエリログのライフサイクルを変更できます。次の SQL ステートメントを実行して、データベースレベルで変更を加えることができます:
ALTER DATABASE <db_name> SET hg_query_log_retention_time_sec = 2592000;
-
パラメーターは秒単位です。ライフサイクルは 3 日から 30 日の間の値に設定でき、これは 259,200 から 2,592,000 秒の範囲に対応します。
-
変更されたライフサイクルは新しいログにのみ適用されます。既存のログは以前の構成に従います。
-
変更されたライフサイクルは新しい接続にのみ適用されます。
-
このパラメーターでライフサイクルを設定した後、期限切れのログは非同期ではなく、すぐにクリーンアップされます。
スロークエリログのエクスポート
Hologres では、INSERT ステートメントを使用して、スロークエリログ (hg_query_log) からカスタムの内部テーブルや MaxCompute や OSS などの外部テーブルにデータをエクスポートできます。
-
注意事項
スロークエリログからデータを正しく効率的にエクスポートするには、次の点に注意してください:
-
INSERT INTO ... SELECT ... FROM hologres.hg_query_log;を実行するアカウントは、hologres.hg_query_logテーブルに対する必要なアクセス権限を持っている必要があります。詳細については、「権限の付与」をご参照ください。インスタンス全体のスロークエリログをエクスポートするには、INSERTコマンドを実行するアカウントがスーパーユーザーまたは pg_read_all_stats 権限を持っている必要があります。そうでない場合、hologres.hg_query_logテーブルからクエリされたデータは不完全になり、エクスポートされたデータも不完全になります。 -
query_start はスロークエリログテーブルのインデックスです。特定の時間範囲のデータをエクスポートするには、クエリ条件に
query_start列を含めてください。これにより、パフォーマンスが向上し、リソース消費が削減されます。 -
query_startを使用して時間範囲でフィルタリングする場合、query_startにネストされた式を使用しないでください。これにより、インデックスがヒットしなくなります。たとえば、WHERE to_char(query_start, 'yyyymmdd') = '20220101';を書くより良い方法は、WHERE query_start >= to_char('20220101', 'yyyy-mm-dd') AND query_start < to_char('20220102', 'yyyy-mm-dd');です。
-
-
例 1:Hologres 内部テーブルへのエクスポート。
Hologres で次のコマンドを実行して、スロークエリログを query_log_download 内部テーブルにエクスポートします。
--Hologres SQL 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[] ); 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'; -
例 2:MaxCompute 外部テーブルへのエクスポート。
-
MaxCompute で次のコマンドを実行して、データを受け取るテーブルを作成します。
CREATE TABLE if NOT EXISTS mc_holo_query_log ( username STRING COMMENT 'クエリのユーザー名' ,status STRING COMMENT 'クエリの最終ステータス:success または failed' ,query_id STRING COMMENT 'クエリ ID' ,datname STRING COMMENT 'クエリのデータベース名' ,command_tag STRING COMMENT 'クエリのタイプ' ,duration BIGINT COMMENT 'クエリ期間 (ミリ秒、ms)' ,message STRING COMMENT 'エラーメッセージ' ,query STRING COMMENT 'クエリのテキストコンテンツ' ,read_rows BIGINT COMMENT 'クエリによって読み取られた行数' ,read_bytes BIGINT COMMENT 'クエリによって読み取られたバイト数' ,memory_bytes BIGINT COMMENT '単一ノードでのピークメモリ消費量 (正確ではありません)' ,shuffle_bytes BIGINT COMMENT 'データシャッフルの推定バイト数 (正確ではありません)' ,cpu_time_ms BIGINT COMMENT '合計 CPU 時間 (ミリ秒、正確ではありません)' ,physical_reads BIGINT COMMENT '物理読み取りの回数' ,application_name STRING COMMENT 'クエリのアプリケーションタイプ' ,engine_type ARRAY<STRING> COMMENT 'クエリに使用されるエンジン' ,table_write STRING COMMENT 'SQL ステートメントがデータを書き込むテーブル' ,table_read ARRAY<STRING> COMMENT 'SQL ステートメントがデータを読み取るテーブル' ,plan STRING COMMENT 'クエリの実行計画' ,optimization_cost BIGINT COMMENT 'クエリ実行計画を生成するための時間' ,start_query_cost BIGINT COMMENT 'クエリの起動時間' ,get_next_cost BIGINT COMMENT 'クエリの実行期間' ,extended_cost STRING COMMENT 'クエリのその他の詳細なコスト' ,query_detail STRING COMMENT 'クエリに関するその他の拡張情報 (JSON 形式で保存)' ,query_extinfo ARRAY<STRING> COMMENT 'クエリに関するその他の拡張情報 (ARRAY 形式で保存)' ,query_start STRING COMMENT 'クエリの開始時刻' ,query_date STRING COMMENT 'クエリの開始日' ) COMMENT 'hologres インスタンスのクエリログ日次' PARTITIONED BY ( ds STRING COMMENT '統計日' ) LIFECYCLE 365; ALTER TABLE mc_holo_query_log ADD PARTITION (ds=20220803); -
Hologres で次のコマンドを実行して、スロークエリログを MaxCompute 外部テーブルにエクスポートします。
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';
-
設定項目
Hologres は、特定のクエリを記録するのに役立つ次の設定項目を提供します。
log_min_duration_statement
-
説明:
この項目は、クエリがスロークエリとしてログに記録されるための最小期間を指定します。デフォルトでは、システムは 100 ms を超えて実行されるクエリを収集しますが、1 秒を超えて実行されるクエリのみが表示されます。この項目を使用して表示のしきい値を変更できます。注意:
-
この項目の変更は新しいクエリにのみ適用されます。以前に収集されたクエリは、元のデフォルト値に基づいて表示されます。
-
この設定を変更できるのはスーパーユーザーのみです。
-
クエリのログ記録を停止するには、
-1に設定します。正の数に設定する場合、最小値は 100 ms です。
-
-
例:
しきい値を設定して、
250 ms以上実行されるすべての SQL ステートメントがログに記録され、クエリできるようにします:-- DB レベルで設定 (スーパーユーザーが必要) ALTER DATABASE dbname SET log_min_duration_statement = '250ms'; -- 現在のセッションレベルで設定 (一般ユーザーが実行可能) SET log_min_duration_statement = '250ms';
log_min_duration_query_stats
-
説明:
この項目は、クエリの実行統計を記録します。デフォルトでは、システムは 10 秒を超えて実行されるクエリの統計を記録します。注意:
-
この項目の変更は新しいクエリにのみ適用されます。以前に記録されたクエリは、元のデフォルト値に基づいて表示されます。
-
クエリ統計の記録を停止するには、
-1に設定します。 -
この情報には大量のストレージが必要です。情報を記録しすぎると、スロークエリログの分析が遅くなる可能性があります。したがって、特定の問題をトラブルシューティングする場合にのみ 10 秒未満に設定できます。それ以外の場合は、より小さい値に設定しないでください。
-
-
例:
システムが 20 秒を超えて実行されるクエリの統計を記録するように設定します:
--DB レベルで設定 (スーパーユーザーが必要) ALTER DATABASE dbname SET log_min_duration_query_stats = '20s'; -- 現在のセッションレベルで設定 (一般ユーザーが実行可能) SET log_min_duration_query_stats = '20s';
log_min_duration_query_plan
-
説明:
この項目は、クエリの実行計画情報を記録します。デフォルトでは、システムは 10 秒以上のスロークエリログの実行計画を表示します。注意:
-
この項目の変更は新しいクエリにのみ適用されます。以前に記録されたクエリは、元のデフォルト値に基づいて表示されます。
-
ステートメントの実行時間が設定されたミリ秒数以上の場合、その実行計画はスロークエリログに記録されます。
-
一般的に、
EXPLAINを使用して実行計画を即座に取得できます。別途記録する必要はありません。 -
クエリ実行計画の記録を停止するには、
-1に設定します。
-
-
例:
システムが 10 秒を超えるクエリログの実行計画を記録するように設定します:
-- DB レベルで設定 (スーパーユーザーが必要) ALTER DATABASE dbname SET log_min_duration_query_plan = '10s'; -- 現在のセッションレベルで設定 (一般ユーザーが実行可能) SET log_min_duration_query_plan = '10s';
よくある質問
-
症状:
Hologres V1.1 でスロークエリログを表示すると、クエリされた行数や返された行数などの情報が表示されません。
-
原因:
スロークエリログの収集が不完全です。
-
解決策:
Hologres V1.1.36 から V1.1.49 では、次の GUC パラメーターを使用して完全な情報を表示できます。この情報は Hologres V1.1.49 以降ではデフォルトで表示されます。
説明Hologres インスタンスが V1.1.36 より前のバージョンの場合は、「一般的なアップグレード準備エラー」をご参照いただくか、Hologres DingTalk グループに参加してフィードバックをお寄せください。詳細については、「オンラインサポートの利用方法」をご参照ください。
-- (推奨) データベースレベルで、データベースごとに 1 回設定します。 ALTER DATABASE <db_name> SET hg_experimental_force_sync_collect_execution_statistics = ON; -- セッションレベルで SET hg_experimental_force_sync_collect_execution_statistics = ON;db_name はデータベースの名前です。
関連資料
インスタンス内のクエリを診断および管理するには、「クエリの管理」をご参照ください。