このトピックでは、Hologres における ANALYZE コマンドと、自動統計情報収集のための AUTO ANALYZE の動作について説明します。主な動作パラメーターを解説し、統計情報収集を理解・制御することで、クエリプランの品質向上を図ります。
統計情報および ANALYZE の概要
統計情報が必要な理由
オプティマイザーは、合理的な実行計画を生成するためにテーブルおよび列の統計情報に依存します。具体的には以下の情報を使用します。
-
行数および列数
-
列幅 (Width)
-
個別値の数 (NDV)
-
最頻値 (MCV) およびその出現頻度
-
ヒストグラムおよびその他の分布特性
これらの情報により、オプティマイザーは以下を実現します。
-
演算子の実行コストを推定する
-
実行計画の探索空間を削減する
-
適切な結合順序および結合アルゴリズムを選択する
-
メモリおよび並列処理を推定する
これにより、より最適な実行計画が得られます。
ANALYZE コマンドは、ユーザーが能動的にテーブル/列の統計情報を収集するための標準的な方法です。統計情報が不足または不正確な場合、クエリプランが著しく劣化することがあります(例:異常な結合順序)。これは、クエリ OOM、実行時間の長期化、インスタンス CPU 使用率の急上昇などの症状として現れます。
AUTO ANALYZE は、Hologres システムがテーブル/列の統計情報を自動的に収集するための標準的な方法です。AUTO ANALYZE は非同期のバックグラウンドシステム動作であるため、テーブルデータが変更されてから、AUTO ANALYZE が変更を検出し、スケジューリングして自動統計情報収集を完了するまで、数十秒から数分の遅延が発生します。そのため、特定のシナリオでは、ユーザーが手動で ANALYZE を実行し、統計情報がタイムリーに収集されることを推奨します。
ANALYZE を手動で実行すべきタイミング
以下のシナリオでは、手動実行を推奨します。
-
テーブルに対して大量のデータをインポート/更新/削除する
INSERT/UPDATE/DELETE操作を行った後、直ちにクエリを実行する場合は、INSERT/UPDATE/DELETE実行後に当該テーブルに対して ANALYZE を実行してください。 -
複数テーブル結合のパフォーマンスが著しく低下した場合は、重要な結合列および Group By 列に対して列レベルの ANALYZE を実行してください。
-
外部テーブルに対して
CREATE FOREIGN TABLEまたはIMPORT FOREIGN SCHEMAを実行した後、直ちにクエリを実行する場合は、クエリ実行前に新規作成された外部テーブルに対して ANALYZE を実行し、初期統計情報を収集することを推奨します。 -
CREATE EXTERNAL DATABASEを実行した後、直ちにクエリを実行する場合は、クエリ実行前に外部データベース配下のクエリ対象テーブルに対して ANALYZE を実行することを推奨します。 -
以下のいずれかのエラーまたは症状が発生した場合:
-
複数テーブル結合時の OOM エラー:
Query executor exceeded total memory limitation ...またはQuery exceed per query memory limitation ... -
複数テーブル結合エラー:
Capacity error: BinaryArray cannot contain more than 2147483646 bytes ... -
インポートまたはクエリタスクの実行時間が異常に長く、CPU 使用率が不均等になる。
-
EXPLAIN <SQL>の結果に、推定行数が 1000 行の Scan 演算子が表示される場合:-> Seq Scan on tbl (cost=0.00..5.00 rows=1000 width=1)。これはテーブルに統計情報がないことを示します。 -
EXPLAIN <SQL>の結果に、推定行数が 1 行の Scan 演算子が表示される場合:-> Seq Scan on tbl (cost=0.00..1.00 rows=1 width=1)。これはテーブルの行数が 0 行と推定されていることを示します。実際の Scan 結果が 0 行でない場合は、統計情報が古くなっている可能性があるため、手動での ANALYZE を推奨します。
-
上記のシナリオでは、まず手動で ANALYZE を実行し、パフォーマンスが回復するかどうかを確認した後、AUTO ANALYZE の構成をさらに調整することを推奨します。
ANALYZE コマンド
基本構文および動作
-
テーブル全体のすべての列に対して統計情報を収集する
ANALYZE table_name;
-
テーブルの行数を収集し、テーブル内のすべての通常列に対して一様に Width、MCV、ヒストグラム、NDV などの統計情報を収集します。
-
さまざまな統計値を推定するためにサンプリングに基づくアプローチを使用します。サンプリング操作は、ANALYZE プロセス内でサブ SQL を起動します。
-
デフォルトでは、ANALYZE はテーブルからランダムに 30,000 行をサンプリングして統計情報を収集・計算します。テーブルの行数が 30,000 行未満の場合は、すべての行をサンプリングします。
-
特定の列のみに対して統計情報を収集する(重要な列に対して推奨)
ANALYZE table_name(col1, col2, ...);
-
指定された列に対してより正確な NDV を計算します(通常は
APPROX_COUNT_DISTINCTロジックを使用)。これはテーブルレベルのサンプリングよりも正確ですが、コストがかかります。 -
MCV、ヒストグラム、Width などの統計情報は引き続きサンプリングによって取得されます。
-
同じ列に対して
ANALYZEを複数回実行すると、後の実行でその列の古い統計情報が上書きされますが、他の指定されていない列には影響しません。
列数が多いテーブルの場合、ANALYZE table_name; は ANALYZE table_name(col1, col2, ...) と完全に同等ではありません。後者は通常 NDV においてより正確ですが、コストがかかります。頻繁に使用される結合列、Group By 列、その他の重要な列に対して列レベルの ANALYZE を補足的に実行することを推奨します。
制限事項および考慮事項
-
分析されない列
-
サポートされていない型:列の型がユーザ定義型であるか、Hologres が統計情報収集をサポートしていない型セットに含まれる場合、統計情報収集はスキップされます。
-
ANALYZE をサポートしない列の型には次が含まれます。「char」(単一文字型)、BIT、VARBIT、BYTEA、NAME、JSON、TSVECTOR、TSQUERY、OID、XID、CID、INET、POINT、LINE、LSEG、BOX、CIRCLE、PATH、POLYGON、BITARRAY、VARBITARRAY、BYTEAARRAY、INT2ARRAY、MONEYARRAY、NUMERICARRAY、TIMEARRAY、TIMETZARRAY、TIMESTAMPTZARRAY、TIMESTAMPARRAY、ANYARRAY、REGCLASS、DATEARRAY、その他の INTERNAL 型。
-
列の型がサポートされていない場合、手動 ANALYZE および AUTO ANALYZE の両方が無視されます。
-
パーティションテーブルの場合、増分パーティション統計情報のマージをサポートしない列の型も分析されません。上記に加えて、サポートされていない型には BOOLARRAY、INT4ARRAY、TEXTARRAY、BPCHARARRAY、VARCHARARRAY、INT8ARRAY、FLOAT4ARRAY、FLOAT8ARRAY も含まれます。
-
-
削除済みとしてマークされた列:
ALTER TABLE ... DROP COLUMN後に保持される論理列(attisdropped = true)は分析されません。 -
列属性によって明示的に無効化されている場合:
-
列属性
enable_analyze = falseが設定されている列は、ANALYZE および AUTO ANALYZE の対象外になります。 -
列属性
enable_auto_analyze = falseが設定されている列は、AUTO ANALYZE の対象外になります。 -
これらの列属性の詳細については、以降のセクションをご参照ください。
-
-
JSONB 列の統計情報が有効になっていない場合:
-
列の型が
JSONBであり、enable_jsonb_statsが有効になっていない場合、その列の JSONB 統計情報は収集されません。 -
JSONB 列の統計情報に依存する必要がある場合(例:複雑な JSON フィルター条件)、まず列属性で
enable_jsonb_statsを有効にする必要があります。
-
-
まとめ: ANALYZE table_name; を実行しても、上記の型または列属性の制限により、一部の列がスキップされる可能性があります。pg_stats で対応する統計情報レコードが見つからない場合は、まずこれらの制限を確認してください。
-
データレイクテーブルに対する ANALYZE の制限事項
-
特定の Timestamp、Version、Branch、Snapshot、または Tag に対して個別に ANALYZE はサポートされていません。
-
典型的な使用方法
-
推奨される典型的な使用方法
-
結合列、Group By 列、フィルター条件列に対して列レベルの ANALYZE を実行します。
-
ANALYZE tablename (order_id, user_id, dt);
ANALYZE tablename;
ANALYZE foreign_table;
-
列属性を設定して特定の列の統計情報収集をスキップする
-
Hologres は、列レベルの属性を通じて、列に対して ANALYZE または AUTO ANALYZE を実行するかどうかを制御できます。これは以下のシナリオに適用されます。
-
超ワイド列(非常に長い Text など)は統計情報収集のオーバーヘッドが高く、クエリプランへの恩恵が限定的またはゼロである。
-
特定の列が結合、フィルター、集約に一切関与せず、統計情報収集が不要である。
-
ANALYZE または AUTO ANALYZE のリソース消費を削減する必要がある。
-
-
制御パラメーターは以下の列オプションです。
-
enable_analyze:列が手動 ANALYZE および自動 AUTO ANALYZE に参加するかどうかを制御します。デフォルトはtrueです。 -
enable_auto_analyze:列が自動 AUTO ANALYZE に参加するかどうかのみを制御します。デフォルトはtrueです。
-
-
設定方法(
ALTER TABLEコマンド経由):
-
-- 特定の列に対して ANALYZE および AUTO ANALYZE を無効化
ALTER TABLE t ALTER COLUMN bitmap_col SET (enable_analyze = false);
-- 特定の列に対して AUTO ANALYZE を無効化(手動 ANALYZE は許可)
ALTER TABLE t ALTER COLUMN large_text_col SET (enable_auto_analyze = false);
-- デフォルト動作を復元(再有効化)
ALTER TABLE t ALTER COLUMN bitmap_col RESET (enable_analyze);
ALTER TABLE t ALTER COLUMN large_text_col RESET (enable_auto_analyze);
パーティションテーブルおよび増分パーティション ANALYZE
大規模なパーティションテーブルに対して ANALYZE を実行する際のオーバーヘッドを軽減するため、Hologres は増分パーティション ANALYZE をサポートしています。
-
目的:
-
親テーブルのフルサンプリングを毎回回避する。
-
子パーティションに対して
ANALYZEを実行し、統計情報をマージすることで親テーブルの統計情報を更新する。 -
変更されていない子パーティションの統計情報収集をスキップする。
-
適用範囲および制限事項
-
Hologres V2.0 以降では、増分パーティション ANALYZE は手動構成なしでデフォルトで有効になっています。詳細については、プロダクトバージョンノートをご参照ください。
-
有効化されている場合、子パーティションに対して
ANALYZEを実行すると、その統計情報を他の子パーティションの統計情報と組み合わせて親テーブルの統計情報を生成しようとします。 -
親テーブルの統計情報をマージする前提条件は、現在分析中の子パーティション以外に、親テーブル配下のすべての他の子パーティションがすでに統計情報を持っていること(行数統計および列統計を含む)です。
-
そのため、以下の操作が可能です。
-
初期設定時、まず親テーブルに対して
ANALYZEを実行します。システムはANALYZEが必要な子パーティションを自動検出し、1 つずつ分析し、最終的に結果を親テーブルの統計情報にマージします。 -
後で新しいパーティションが追加された場合、新たに追加された子パーティションに対してのみ
ANALYZEを実行すれば十分です。
-
簡単な例
BEGIN;
DROP TABLE IF EXISTS t_parent;
CREATE TABLE t_parent(a int, b int) PARTITION BY LIST (a);
CREATE TABLE child1 PARTITION OF t_parent FOR VALUES IN (1);
CREATE TABLE child2 PARTITION OF t_parent FOR VALUES IN (2);
COMMIT;
insert into child1 values (1, 1), (1, 1), (1, 1), (1, 1), (1, 1), (1, 1), (1, 1), (1, 1), (1, 1), (1, 2);
insert into child2 values (2, 1), (2, 2), (2, 3), (2, 4), (2, 5), (2, 5), (2, 5), (2, 5), (2, 5), (2, 5);
-- child2 に統計情報がないため、親テーブルの統計情報をマージできません
dbname=# ANALYZE child1;
INFO: auto merging of leaf partition stats to calculate root partition stats is not possible because partition child2 is not analyzed
ANALYZE
-- child1 にはすでに統計情報があります。child2 を分析後、親テーブルの統計情報が自動的にマージされます
dbname=# ANALYZE child2;
ANALYZE
dbname=# SELECT tablename,
attname,
null_frac AS "NF",
avg_width,
n_distinct,
most_common_vals AS "MCV",
most_common_freqs AS "MCV_FRAQ"
FROM pg_stats
WHERE tablename = 't_parent';
tablename | attname | NF | avg_width | n_distinct | MCV | MCV_FRAQ
-----------+---------+----+-----------+------------+-------+------------
t_parent | a | 0 | 4 | 2 | {1,2} | {0.5,0.5}
t_parent | b | 0 | 4 | -0.2 | {1,5} | {0.45,0.3}
(2 rows)
-- これ以降、新しいパーティションが追加された場合、子パーティションに対してのみ ANALYZE を実行すれば、親テーブルの統計情報は子パーティションのサンプリングのみを通じて自動的にマージされます。
親テーブルに対する ANALYZE
パーティションテーブルの複数の子パーティションでデータ変更が発生し、個別に各子パーティションに対して ANALYZE を実行したくない場合があります。このようなケースでは、親テーブルに対して一度だけ ANALYZE を実行できます。
増分パーティション ANALYZE が有効になっている場合、親テーブルに対して手動で ANALYZE を実行すると、システムはすべての子パーティションを盲目的に分析するのではなく、統計情報の更新が必要な子パーティションを適応的に選択します。このメカニズムにより、大規模なパーティションテーブルに対する ANALYZE のオーバーヘッドを大幅に削減しつつ、統計情報の精度を確保できます。
動作説明
ANALYZE partition_parent_table; を実行すると、システムは以下の 2 種類の子パーティションを自動的に識別し、それらの ANALYZE 統計情報を優先的に収集した後、親テーブルの統計情報にマージします。
-
統計情報変更済みパーティション
-
前回の
ANALYZE以降、子パーティションのデータに大幅な変更(挿入、更新、削除)が発生している。 -
判定基準:
-
変更された行数が変更しきい値(
前回 ANALYZE 時の行数の 1%)に達している。
-
-
-
マージ不可パーティション
-
子パーティションに完全な統計情報がなく、親テーブルの統計情報マージに参加できない。
-
一般的な原因:
-
ANALYZE が一度も実行されていない:子パーティションの統計情報が完全に欠落している。
-
列統計情報が欠落している:指定された列に必要な統計情報(MCV、ヒストグラム、NDV HLL カウンターなど)が不足している。
-
統計情報の型が列の型と一致しない:子パーティションの列の型が変更され、既存の統計情報が現在の列の型と不整合を起こしている。
-
統計情報のバージョンが古くなっている:親テーブルの統計情報バージョン(statistic_version)が最新の子パーティションの統計情報バージョンよりも低く、親テーブルの統計情報が最新でないことを示しており、再マージが必要である。
-
-
実行例および出力
-- 親テーブルに対して ANALYZE を実行
ANALYZE partition_parent_table;
典型的な出力:
INFO: will analyze 5 part tables first (stats changed 3, unable-to-merge 2)
この出力は以下を示しています。
-
システムは統計情報収集を優先的に必要とする 5 つの子パーティション を識別しました。
-
そのうち、3 つの子パーティション はデータの大幅な変更により統計情報の更新が必要です。
-
そのうち、2 つの子パーティション は統計情報が欠落または使用不能であるため「マージ不可」とマークされ、内部で ANALYZE をトリガーする必要があります。
注意事項
-
子パーティションに対して
autovacuum_enabled = false(テーブルレベルで AUTO ANALYZE を無効化)を設定することは推奨されません。これにより、子パーティションが「マージ不可」状態のまま長期間維持され、手動で再度 ANALYZE を実行しない限り解決しません。
このメカニズムにより、Hologres は大規模なパーティションテーブルに対する ANALYZE の実行効率を大幅に向上させつつ、統計情報の品質を確保し、クエリオプティマイザーにタイムリーかつ正確な意思決定データを提供できます。
論理パーティションテーブルに対する ANALYZE
論理パーティションテーブルは、Hologres に特有のパーティションテーブルタイプです。標準的な PostgreSQL パーティションテーブル(PARTITION BY により物理的な子テーブルを作成)とは異なり、論理パーティションテーブルは物理的には単一テーブルのままであり、パーティション列の値に基づいて論理的にのみデータをパーティション化し、より柔軟なパーティション管理機能を提供します。
論理パーティションテーブルに対する ANALYZE のロジックは、物理パーティションテーブルと基本的に同じです。唯一の違いは、論理パーティションテーブルの子パーティションが別個のテーブルではない点ですが、物理的な子パーティションと同様に、それぞれが独立した行数統計および列統計を持ちます。
動作説明
論理パーティションテーブルに対して ANALYZE を実行すると、システムは物理パーティションテーブルと類似しながらも独立した処理ロジックを使用します。
-
論理パーティションの自動検出
-
論理パーティション(親)テーブルに対して
ANALYZE logical_partitioned_table;を実行すると、システムはストレージエンジンに問い合わせてテーブルのすべての論理パーティションを自動的に照会します。
-
-
統計情報が必要な論理パーティションの適応的選択
-
物理パーティションテーブルと同様に、システムは以下の論理パーティションを識別し、統計情報収集を優先します。
-
統計情報変更済みパーティション
-
前回の
ANALYZE以降、子パーティションのデータに大幅な変更(挿入、更新、削除)が発生しており、上記で説明した物理パーティションテーブルと同じ判定基準を適用します。 -
統計情報が欠落している論理パーティション:ANALYZE が一度も実行されていない、または指定された列に必要な統計情報(HLL カウンターなど)が不足している。
-
統計情報が使用不能な論理パーティション:列統計情報が現在の列の型と一致していない、または統計情報が古くなっている。
-
-
空のパーティションはスキップされます:行数が 0 の論理パーティションは自動的に無視されます。
-
システムは情報メッセージを出力します。例:
INFO: will analyze 10 logical partitions first -
-
パーティションごとのサンプリングおよび統計情報収集
-
統計情報収集が必要な各論理パーティションに対して、システムはパーティション列のフィルター条件(例:
WHERE user_id = 1 AND event_date = '2024-11-04')を含むサンプリングクエリを構築します。 -
その論理パーティションの範囲内でデータサンプリングを実行し、列レベルの統計情報(NDV、MCV、ヒストグラム、HLL カウンターなど)を収集します。
-
統計情報は 論理パーティション の粒度で
hologres_statistic.hg_table_statisticに格納され、異なる論理パーティションはunique_nameフィールドで区別されます。
-
-
親テーブル統計情報のマージ
-
すべての論理パーティションの統計情報収集が完了すると、システムは自動的に統計情報のマージをトリガーして親テーブルの統計情報を生成します。
-
実行例および出力
例 1:論理パーティション親テーブルに対して ANALYZE を実行
-- 論理パーティションテーブルを作成
CREATE TABLE user_events (
user_id INT NOT NULL,
event_type TEXT NOT NULL,
event_date DATE NOT NULL,
event_data INT
)
LOGICAL PARTITION BY LIST(user_id, event_date);
-- 異なる論理パーティションにデータを挿入
INSERT INTO user_events SELECT 1, 'login', '2024-11-01', i FROM generate_series(1, 1000) i;
INSERT INTO user_events SELECT 1, 'logout', '2024-11-02', i FROM generate_series(1, 1000) i;
INSERT INTO user_events SELECT 2, 'purchase', '2024-11-03', i FROM generate_series(1, 1000) i;
INSERT INTO user_events SELECT 3, 'view', '2024-11-04', i FROM generate_series(1, 1000) i;
-- 親テーブルに対して ANALYZE を実行
ANALYZE VERBOSE user_events;
典型的な出力:
INFO: will analyze 4 logical partitions first
INFO: analyzing hologres table "public.user_events" PARTITION (user_id=1,event_date='2024-11-01')
INFO: analyzing hologres table "public.user_events" PARTITION (user_id=1,event_date='2024-11-02')
INFO: analyzing hologres table "public.user_events" PARTITION (user_id=2,event_date='2024-11-03')
INFO: analyzing hologres table "public.user_events" PARTITION (user_id=3,event_date='2024-11-04')
INFO: try to merge root partition
INFO: automatically merging leaf partition stats to calculate root partition stats
説明:
-
システムは統計情報の更新が必要な 4 つの論理パーティションを自動的に検出しました。
-
各論理パーティションの統計情報を 1 つずつ収集しました。
-
最後に、親テーブルのグローバル統計情報を自動的にマージおよび生成しました。
例 2:指定された論理パーティションに対して ANALYZE を実行
-- 単一の論理パーティションに対して ANALYZE を実行
ANALYZE user_events PARTITION (user_id=1, event_date='2024-11-01');
-- 複数の論理パーティションに対して ANALYZE を実行
ANALYZE user_events
PARTITION (user_id=1, event_date='2024-11-01')
PARTITION (user_id=2, event_date='2024-11-03');
-- 指定された論理パーティションの特定の列に対して ANALYZE を実行
ANALYZE user_events
PARTITION (user_id=1, event_date='2024-11-01') (user_id, event_type);
説明:
-
PARTITION句を使用して、分析対象の論理パーティションを指定できます。 -
複数の論理パーティションを同時に指定できます。
-
標準的な ANALYZE と同様に、統計情報を収集する列をさらに指定できます。
統計情報の保存場所
論理パーティションテーブルの統計情報は、hologres_statistic.hg_table_statistic テーブルに保存されます。
SELECT
unique_name,
schema_name,
table_name,
total_rows,
sample_rows,
nattr
FROM hologres_statistic.hg_table_statistic
WHERE table_name = 'user_events'
ORDER BY unique_name;
出力例:
| unique_name | schema_name | table_name | total_rows | sample_rows | nattr |
|-------------|-------------|------------|------------|-------------| ----- |
| user_events | public | user_events | 4000 | 0 | 4 |
| user_events.a1b2c3d4e5f6... | public | user_events | 1000 | 1000 | 4 |
| user_events.f6e5d4c3b2a1... | public | user_events | 1000 | 1000 | 4 |
| user_events.1234567890ab... | public | user_events | 1000 | 1000 | 4 |
| user_events.abcdef123456... | public | user_events | 1000 | 1000 | 4 |
フィールドの説明:
-
親テーブルレコード:
-
total_rows = 4000:すべての論理パーティションにわたる合計行数。 -
sample_rows = 0:親テーブルの統計情報はマージによって導出され、直接サンプリングは行われません。
-
-
論理パーティションレコード(
unique_nameには統計情報オブジェクト(テーブル/パーティション)を識別する MD5 ハッシュが含まれます):-
各論理パーティションには独立した統計情報レコードがあります。
-
sample_rows = 1000:その論理パーティションに対して実際にサンプリングされた行数。
-
論理パーティションテーブル ANALYZE のベストプラクティス
-
論理パーティション親テーブルに対して ANALYZE を実行することを推奨
-
論理パーティション親テーブルに対して
ANALYZEを実行すると、システムがすべての論理パーティションを自動的に検出し、統計情報を収集するため、各パーティションを手動で指定する必要がありません。 -
特定の論理パーティションの統計情報を迅速に更新する必要がある場合にのみ、
PARTITION句を使用してパーティションを指定してください。
-
-
増分統計情報更新を活用する
-
少数の論理パーティションにのみデータが書き込まれる場合、それらのパーティションに対してのみ ANALYZE を実行できます。
-
システムは親テーブルの統計情報マージを自動的にトリガーし、すべてのパーティションの統計情報を再収集する必要はありません。
-
-
論理パーティションの数に注意する
-
論理パーティションの数が多すぎる場合(例:数千)、初期 ANALYZE に時間がかかる可能性があります。オフピーク時間帯に実行することを推奨します。
-
-
論理パーティションテーブルのバージョン関連のパフォーマンス考慮事項
-
V4.1.20 より前のバージョンでは、論理パーティションテーブルに対して ANALYZE を実行すると、パフォーマンスが著しく低下する可能性があります(実行時間が長くなり、約 10 秒間隔で一時停止が発生)。これは、前景の ANALYZE プロセスとバックグラウンドの統計情報ロードタスク(trigger load stats)間のロック競合が原因です。ANALYZE が同じ論理パーティションテーブルのサブパーティションを繰り返し処理する際に、継続的に統計情報 binlog エントリを生成し、同じテーブルおよびバージョンに対して繰り返しバックグラウンド統計情報ロードがトリガーされ、SUE(Statistics Update Exclusive)ロック競合が発生します。
-
V4.2.5 以降のバージョンでは、バックグラウンド統計情報ロードプロセスの重複排除により、同じテーブルおよびバージョンに対する冗長なロード操作が排除され、この問題が最適化されています。論理パーティションテーブルに対する ANALYZE のパフォーマンスが遅い場合は、V4.2.5 以降へのアップグレードを推奨します。
-
-
AUTO ANALYZE と併用する
-
論理パーティションテーブルも AUTO ANALYZE によって管理され、統計情報の更新が必要な論理パーティションを自動的に識別します。
-
ANALYZE コマンドの構成可能パラメーター
|
パラメーター |
説明 |
サポートバージョン |
デフォルト値 |
注記 / 使用例 |
|
hg_experimental_analyze_foreign_partitions_access_limit |
外部テーブルに対して ANALYZE を実行する際、ランダムサンプリング中にアクセス可能なパーティションの最大数 |
v0.10 以降 |
0(無制限) |
-- ランダムサンプリングが外部テーブルのデータを過剰にスキャンするのを防ぐため、100 パーティションのみをサンプリングします。 ALTER DATABASE dbname SET hg_experimental_analyze_foreign_partitions_access_limit = 100; |
|
hg_analyze_foreign_table_max_sample_row_count |
外部テーブルに対して ANALYZE を実行する際、ランダムサンプリング中にサンプリング可能な最大行数 |
v4.1 以降 |
0(無制限)。詳細については、バージョンアップデートをご参照ください。 |
AUTO ANALYZE 自動統計情報収集
Hologres V0.10 以降、Hologres は自動統計情報収集メカニズム AUTO ANALYZE をサポートしています。
-
テーブル作成、データ書き込み、データ変更に基づき、統計情報の更新が必要なテーブルを自動的に判断します。
-
バックグラウンドで非同期に統計情報収集タスクをスケジューリングし、ユーザーが各テーブルに対して手動で ANALYZE を実行する必要をなくします。
-
ANALYZE 操作の見落としによる統計情報の欠落リスクを軽減します。
スイッチおよび適用範囲
データベースレベルのスイッチ
-
構成可能なパラメーターは
hg_enable_start_auto_analyze_workerです。Hologres V0.10 以降、デフォルトで有効になっています。
-- 現在のデータベースで AUTO ANALYZE が有効かどうかを確認
SHOW hg_enable_start_auto_analyze_worker;
-- 無効化(一時的なトラブルシューティング時のみ使用)
ALTER DATABASE dbname SET hg_enable_start_auto_analyze_worker = OFF;
-- デフォルト値 ON にリセット(推奨)
ALTER DATABASE dbname RESET hg_enable_start_auto_analyze_worker;
注記:上記の GUC はデータベースレベルの構成です。SESSION レベルまたは ROLE レベルの構成は無効です。ALTER DATABASE を通じて設定し、その DB にのみ適用される必要があります。また、スーパーユーザのみが変更できます。
テーブルレベルのスイッチ
Hologres は、個々のテーブルに対する AUTO ANALYZE の動作を制御できます。
動作説明
-
単一テーブルの AUTO ANALYZE を無効化
ALTER TABLE my_table SET (autovacuum_enabled = false);
-
単一テーブルの AUTO ANALYZE を有効化(デフォルト動作を復元)
-- 推奨:リセットしてデフォルトを復元
ALTER TABLE my_table RESET (autovacuum_enabled);
-- または明示的に true に設定(非推奨)
ALTER TABLE my_table SET (autovacuum_enabled = true);
-
テーブルの autovacuum_enabled ステータスを確認
SELECT relname, reloptions FROM pg_class WHERE relname = 'my_table';
relname | reloptions
----------+----------------------------
my_table | {autovacuum_enabled=false}
(1 row)
典型的なユースケース
-
統計情報が不要な特殊な業務テーブル
-
一部のテーブルは一時的な保存またはログ記録専用であり、複雑なクエリに参加しないため、統計情報収集は不要です。
-
データ量が多く、頻繁に変更されるが統計情報が不要なテーブルは、
autovacuum_enabled = falseを設定することで、不要なリソース消費を回避できます。
-
-
統計情報がすでに手動で維持されている
-
特定の重要なテーブルについては、すでに業務要件を満たす定期的な手動 ANALYZE ワークフローが確立されている場合があります。
-
-
リソース使用量を削減するために一時的に無効化
-
業務ピーク時または緊急トラブルシューティング中に、特定のテーブルの AUTO ANALYZE を一時的に無効化できます。
-
状況が解決したら、再度有効化するか、手動で ANALYZE を実行してください。
-
考慮事項
-
パーティションテーブルの場合:
-
子パーティションに対して
autovacuum_enabled = falseを設定することは推奨されません。これにより、子パーティションが「マージ不可」状態のまま長期間維持され、親テーブルの統計情報の精度に影響を与える可能性があります。 -
無効化する必要がある場合は、親パーティションテーブルに対してのみ設定することを推奨します。
-
-
テーブルレベルのスイッチはデータベースレベルのスイッチよりも優先度が高くなります。
-
データベースレベルの AUTO ANALYZE が有効であっても、
autovacuum_enabled = falseが設定されたテーブルは AUTO ANALYZE の対象外になります。
-
列レベルのスイッチ
Hologres は、列レベルの属性を通じて、特定の列に対して ANALYZE または AUTO ANALYZE を実行するかどうかを制御できます。これは以下のシナリオに適用されます。
-
ワイド列(長い Text フィールドなど)は統計情報収集のオーバーヘッドが高いが、クエリプランへの恩恵が限定的である。
-
特定の列が結合、フィルター、集約に一切関与せず、統計情報収集が不要である。
-
AUTO ANALYZE のリソース消費を削減する必要がある。
制御パラメーターは以下の列オプションです。
-
enable_auto_analyze:列が自動 AUTO ANALYZE に参加するかどうかのみを制御します。デフォルトはtrueです。 -
構成方法(
ALTER TABLEコマンド経由):
-- 特定の列に対して AUTO ANALYZE を無効化(手動 ANALYZE は許可)
ALTER TABLE t ALTER COLUMN large_text_col SET (enable_auto_analyze = false);
-- デフォルト動作を復元(再有効化)
ALTER TABLE t ALTER COLUMN large_text_col RESET (enable_auto_analyze);
-
考慮事項:
-
列レベルで
enable_auto_analyze = falseを設定すると、AUTO ANALYZE タスクはその列の統計情報を収集しなくなります。ただし、手動でANALYZE table_name;またはANALYZE table_name(col);を明示的に実行することで、統計情報を収集できます。 -
クエリプランに大きな影響を与える列(例:結合列やフィルター条件列)については、統計情報収集を無効化しないことを推奨します。
-
AUTO ANALYZE のトリガーロジック
AUTO ANALYZE は、特定のテーブルの統計情報更新が必要かどうかを判断するために、複数の種類の信号を組み合わせます。
-
データ変更量
-
通常の Hologres テーブルにのみ適用(外部テーブルを除く)。
-
1 分間隔で、FE が各テーブルで観測した
INSERT/UPDATE/DELETE操作の行数を収集します。変更がしきい値を超えた場合、AUTO ANALYZE がトリガーされます(高速応答)。 -
10 分間隔で、ストレージエンジンから挿入/更新/削除の変更行数を取得します。変更がしきい値を超えた場合、AUTO ANALYZE がトリガーされます(精密較正)。
-
-
スキーマ変更
-
通常の Hologres テーブルにのみ適用(外部テーブルを除く)。
-
1 分間隔で、以下の変更が発生したテーブルを収集し、AUTO ANALYZE を実行します。
-
列の追加 / 削除;
-
パーティションテーブル(論理パーティションテーブルを含む)の子パーティションの ATTACH / DETACH
-
-
-
統計情報の欠落 / 親パーティションテーブルの統計情報マージ不可
-
通常の Hologres テーブルおよび外部テーブルの両方に適用。
-
1 分間隔で、統計情報が欠落しているテーブル/列および増分統計情報マージの条件を満たせない子パーティションを収集します。
-
-
外部テーブル
-
CREATE FOREIGN TABLE、IMPORT FOREIGN SCHEMA、または External Database コンテキスト外の Auto Load メカニズムを通じて導入された外部テーブルにのみ適用。 -
現在、MaxCompute 外部テーブルの AUTO ANALYZE のみをサポートしています。
-
4 時間間隔で、DB 内のすべての外部テーブルを定期的にチェックします。2 回のチェックの間に外部データの変更が発生した場合(基準は、対応する外部テーブルの last_modify_timestamp が 2 回のチェック間隔の間に該当すること)、AUTO ANALYZE がトリガーされます。
-
-
フォールバック統計情報
-
午前 1:00~5:00 の時間帯に、継続的に変更があるがしきい値をトリガーしていないテーブル(>5000 行の変更、<10% の変更量)に対して「フォールバック」AUTO ANALYZE を実行し、列のデータ分布ドリフトをキャプチャします(例:翌日深夜以降に書き込まれた日付型フィールドは前日と完全に異なり、分布が変化する)。
-
-
アクセスホットスポットテーブル(External Database のみ)
-
External Database で
enable_auto_analyzeパラメーターを有効化すると、Hologres システムは前回のシステム起動以降に最近アクセスされたテーブルを追跡し、観測リストに追加します。 -
1 時間間隔で、観測リスト内の「最近頻繁にアクセスされた」テーブルが AUTO ANALYZE をトリガーします。
-
システム再起動後、アクセスされたテーブルリストはクリアされ、記録が再開されます。
-
External Database に対する AUTO ANALYZE
-
Hologres V3.0 以降、Hologres は External Database 機能をサポートしています。External Database を作成する際、AUTO ANALYZE を有効化できます(デフォルトでは無効。詳細についてはリリースノートをご参照ください)。
-- External Database 作成時に AUTO ANALYZE を有効化
-- リファレンス:https://www.alibabacloud.com/help/zh/hologres/developer-reference/create-external-database
CREATE EXTERNAL DATABASE <ext_database_name> WITH
metastore_type 'maxcompute'
mc_project 'project_name'
enable_auto_analyze 'true';
-- 既存の External Database に対して AUTO ANALYZE を有効化
ALTER EXTERNAL DATABASE dbname WITH enable_auto_analyze 'true';
機能制限:V3.2 以前では、External Database に対する AUTO ANALYZE には CREATE EXTERNAL DATABASE 文で Access Key および Access Secret の構成が必要です。SLR または STS で構成された External Database では AUTO ANALYZE はサポートされていません。V4.0 以降ではこのような制限はありません。
-
External Database における AUTO ANALYZE がサポートする
metastore_typeの範囲は次のとおりです:dlf, dlf-paimon, dlf-rest, maxcompute。 -
External Database における AUTO ANALYZE がサポートするテーブル形式は次のとおりです:
MaxCompute, Paimon, Iceberg。 -
External Database における AUTO ANALYZE は、デフォルトで External Database のOwner ID を使用し、Time-based One-Time Password (TOTP) 認証を介して ANALYZE タスクを実行します。Owner が十分なテーブル権限を持っていない場合、システムは AUTO ANALYZE タスクを正常に実行できません。
-
External Database の外部テーブルが AUTO ANALYZE の対象となるには、以下の条件を満たす必要があります。
-
External Database 構成
hg_enable_start_auto_analyze_worker = on(デフォルトは on) -
External Database 属性
enable_auto_analyzeがtrueに設定されている(デフォルトでは設定されておらず、falseとなる。詳細についてはリリースノートをご参照ください) -
External Database Owner がデータレイクプロジェクト(該当する場合)およびテーブルに対するクエリ権限を持っている
-
テーブルが過去 3 日以内に少なくとも 1 回アクセスされている
-
External Database における AUTO ANALYZE は、少なくとも 1 回アクセスされた外部テーブルのみを監視します。
-
システム再起動後、外部テーブルが少なくとも 1 回アクセスされると、AUTO ANALYZE システムはそれを観測リストに追加し、これらのテーブルに対して定期的に AUTO ANALYZE をトリガーします。
-
-
注記:External Database の外部テーブルで一度もアクセスされていないものについては、初回アクセス時に高速行数推定メカニズムを使用して行数を取得し、フォールバック統計情報として使用します(以下の「高速行数推定」セクションをご参照ください)。これにより、ある程度の統計情報カバー率が確保されます。
AUTO ANALYZE のリソース制限
バックグラウンドの AUTO ANALYZE タスクが前景のユーザータスクに影響を与えないように、Hologres は AUTO ANALYZE 機能に対して以下のリソース制限を設けています。
-
AUTO ANALYZE タスク実行時、ワーカーあたりのデフォルトメモリ制限は
4 GBです。テーブルのデータ量が大きすぎる場合、サンプリングがメモリ制限を超え、AUTO ANALYZE サンプリング SQL が失敗する可能性があります。このような場合、行数情報のみが収集され、列分布情報(MCV、ヒストグラム、NDV など)は収集できません。auto_analyze_work_memory_mbを調整することで、この動作を変更できます。インスタンス仕様が大きいほど、AUTO ANALYZE の利用可能なメモリ制限が高くなります。 -
同時にスケジューリングされる AUTO ANALYZE タスクのインスタンスレベル同時実行数は、通常 4 を超えず、極端な場合でも 6 を超えません。
-
同じパーティションテーブル配下の子パーティション AUTO ANALYZE タスクの最大同時スケジューリング同時実行数は 3 です。
-
デフォルトでは、AUTO ANALYZE は最初の 256 列の統計情報を収集します。テーブルの列数が 256 列を超える場合、最初の 256 列のみが収集されます(パーティションテーブルの場合、パーティション列は優先され、位置が 256 を超えていても収集されます)。
hg_experimental_auto_analyze_max_columns_countを調整することで、この値を変更できます。 -
AUTO ANALYZE タスクのサンプリングサブ SQL は、制限付きのクエリ実行レベル同時実行数を持つ低優先度の Background Pool を使用して実行されます。これにより、AUTO ANALYZE タスクは手動 ANALYZE よりも実行時間が長くなりますが、ユーザーがこれを気にする必要はありません。
-
外部テーブルの場合、AUTO ANALYZE はパーティション列(例:MCV)の列統計情報のみを収集します。パーティション列以外の列の統計情報を収集するためにサンプリングは実行されません。
AUTO ANALYZE の構成可能パラメーター
デフォルトでは、Hologres AUTO ANALYZE 機能はパラメーターの変更を必要としません。
まれな業務シナリオ(例:データの書き込み/更新が稀、統計情報が不要なクエリワークロード、AUTO ANALYZE によるシステム負荷の増加)では、特定のデフォルトパラメーターを変更して AUTO ANALYZE の動作を調整し、介入または部分的なパフォーマンスチューニングを行うことができます。
注記:AUTO ANALYZE のデフォルト動作を調整できるのはスーパーユーザのみです。すべてのパラメーターはDB レベルで設定し、次の分以降に有効になります。
-- スーパーユーザ:データベースレベルで AUTO ANALYZE のデフォルトパラメーターを変更
ALTER DATABASE dbname SET <GUC> = <values>;
|
パラメーター |
説明 |
サポートバージョン |
デフォルト値 |
注記 / 使用例 |
|
hg_enable_start_auto_analyze_worker |
AUTO ANALYZE 機能を有効化 |
V0.10 以降 |
on |
-- DB の AUTO ANALYZE を一時的に無効化 |
|
hg_experimental_auto_analyze_max_columns_count |
AUTO ANALYZE が自動的に統計情報を収集する列数 |
V1.1.0 以降 |
256 |
|
|
auto_analyze_work_memory_mb |
AUTO ANALYZE における単一テーブルのメモリ制限(MB 単位) |
V1.1.54 以降 |
4096 |
-- 9 GB に変更 |
|
auto_analyze_work_statement_timeout |
AUTO ANALYZE タスク実行のタイムアウト(ミリ秒単位) |
V2.0 以降 |
3600000 |
-- 3 時間に変更 |
|
hg_experimental_auto_analyze_max_foreign_table_partitions |
AUTO ANALYZE 実行中にアクセス可能な外部テーブルパーティションの最大数 |
V1.1.54 以降 |
100 |
外部テーブルパーティション数が 100 を超える場合、第 1 レベルパーティション値の辞書式順序で上位 100 パーティションの行数を使用して、外部テーブルの全体行数およびパーティション列 MCV をデフォルトで推定します。 |
|
hg_auto_analyze_run_with_serverless_computing |
AUTO ANALYZE がサーバーレスリソースを使用して実行されるかどうか |
V3.1 以降 |
off(サーバーレスインスタンスではデフォルトで on) |
通常、調整は不要です。AUTO ANALYZE は通常、最小限のリソースしか消費せず、低優先度プロセスを使用してバックグラウンドで実行されるため、インスタンス負荷への影響は極めて小さいです。 |
|
hg_auto_analyze_serverless_computing_query_priority |
サーバーレスタスクの優先度(範囲 1~5、値が大きいほど優先度が高い)。注記:hg_auto_analyze_run_with_serverless_computing を先に有効化する必要があります |
V3.1 以降 |
2 |
-- 最高優先度に変更 |
高速行数推定(Fast Num of Rows)
Hologres V3.1 以降、Hologres は高速行数推定機能を導入しました。実行中の SQL クエリのテーブルに統計情報がない、または統計情報が古くなっている可能性があると検出した場合、Hologres は基盤ストレージまたは外部システムのメタデータを通じてテーブルの行数を迅速に推定し、より合理的な実行計画を生成できます。
Hologres V3.2 以降、高速行数推定(Fast Num of Rows)機能はデフォルトで有効になっています。
スイッチ
高速行数推定を有効化する方法:
-- 無効化(一時的なトラブルシューティング時、またはデータベース全体で統計情報が不要な場合のみ使用)
ALTER DATABASE dbname SET hg_experimental_get_fast_num_of_rows = OFF;
-- V3.2 以降:有効化(デフォルト値にリセット)
ALTER DATABASE dbname RESET hg_experimental_get_fast_num_of_rows;
-- V3.1 以前:有効化
ALTER DATABASE dbname SET hg_experimental_get_fast_num_of_rows = ON;
注記:高速行数推定は、完全な統計情報収集に代わるものではありません。重要な業務テーブルについては、引き続き ANALYZE/AUTO ANALYZE を通じて統計情報を最新の状態に保つことを推奨します。
使用制限
-
高速行数推定は、通常のテーブル(パーティションテーブルを含む)、External Database の外部テーブル、その他のシナリオに適用されます。
-
高速行数推定機能によって推定された行数は、完全に正確であるとは限りません。例えば、パフォーマンス上の理由から、Hologres パーティションテーブルでは、最大 60 パーティション(デフォルト)の行数統計のみを使用して、パーティションテーブル全体の行数を推定します。
-
V4.1.15 以前では、外部テーブルタイプ(Foreign Table)に対して高速行数推定はデフォルトで有効になっていません。
hg_experimental_enable_foreign_table_get_fast_num_of_rowsパラメーターを通じて有効化できます。V4.1.16 以降ではデフォルトで有効になっています。 -
外部テーブルタイプの場合、高速行数推定は MaxCompute 外部テーブル、Paimon 外部テーブル、Iceberg 外部テーブルのみをサポートします。
使用例
-
hg_experimental_get_fast_num_of_rows の例
テーブルに統計情報がない場合、高速行数推定を有効化することで、より正確な行数を取得できます。(Hologres V3.2 以降ではデフォルトで有効)
-- V3.2+
create table test_tbl (a int);
insert into test_tbl select * from generate_series (1, 999);
-- 正確な行数推定(rows=999)
explain select count(1) from test_tbl ;
QUERY PLAN
----------------------------------------------------------------------------------------
Final Aggregate (cost=0.00..5.00 rows=1 width=8)
-> Gather (cost=0.00..5.00 rows=10 width=8)
-> Partial Aggregate (cost=0.00..5.00 rows=10 width=8)
-> Local Gather (cost=0.00..5.00 rows=20 width=8)
-> Partial Aggregate (cost=0.00..5.00 rows=20 width=8)
-> Seq Scan on test_tbl (cost=0.00..5.00 rows=999 width=1)
以下は実際の本番環境でのケースです。
この機能が有効になっていない場合、テーブルに統計情報がないと、クエリプランの Scan ノードに行数=1000 と表示されます(統計情報が利用できず、デフォルトの 1000 行という推定値に基づいてプランが生成されていることを示します)。
この機能を有効化した後、テーブルに統計情報がない場合、クエリプランの Scan ノードの行数は 1000 になりません(システムが基盤ストレージエンジンのメタデータを呼び出してテーブルの行数を取得しました)。
高速行数推定の構成可能パラメーター
|
パラメーター |
説明 |
サポートバージョン |
デフォルト値 |
注記 / 使用例 |
|
hg_experimental_get_fast_num_of_rows |
高速行数推定を有効化するかどうか。 |
v3.1 以降 |
off(V3.1) on(V3.2+) |
|
|
hg_experimental_enable_foreign_table_get_fast_num_of_rows |
外部テーブルの行数推定を有効化するかどうか。 |
v3.1 以降 |
off(V4.1.15 以前) on(V4.1.16+) |
-- 有効化方法: ALTER DATABASE dbname SET hg_experimental_enable_foreign_table_get_fast_num_of_rows = on; |
|
hg_experimental_fast_num_rows_foreign_partitions_access_limit |
外部パーティションテーブルの場合、全体推定の基礎として行数を取得するパーティションの最大数。注記:これは外部テーブルの行数推定が有効になっている場合にのみ有効です。 |
v3.1 以降 |
60 |
これは高速行数推定の時間オーバーヘッドを制御するためです。 |
|
hg_get_fast_num_of_rows_holo_partitions_access_limit |
Hologres 物理パーティションテーブルの場合、全体推定の基礎として行数を取得するパーティションの最大数。 |
v3.1 以降 |
60 |
これは高速行数推定の時間オーバーヘッドを制御するためです。 |
ANALYZE および AUTO ANALYZE の実行履歴の確認
ANALYZE および AUTO ANALYZE 実行後、その実行レコードはクエリログに書き込まれます。ユーザーは hologres.hg_query_log ビューを通じて、ANALYZE および AUTO ANALYZE の実行履歴(実行された SQL、実行時間、ステータスなどの情報)を確認できます。
クエリログにおける ANALYZE および AUTO ANALYZE レコードの識別方法
ANALYZE および AUTO ANALYZE とそのサンプリング SQL 文は、クエリログに別々に記録されます。
実行レコードはクエリログで以下の特徴を持ちます。
|
フィールド |
ANALYZE |
AUTO ANALYZE |
説明 |
|
|
ANALYZE を実行したユーザー名 |
|
AUTO ANALYZE は内部システムアカウントを使用して実行され、クエリログでは一律 |
|
|
ANALYZE を実行したセッションのアプリケーション名 |
|
AUTO ANALYZE フレームワーク接続は |
|
|
|
|
|
|
|
|
|
実行されたコマンドの種類 |
|
|
|
|
サンプリングサブ SQL は SELECT 文です。この文を使用してサンプリングのリソース消費を確認できます。 |
ANALYZE とそのサンプリング SQL は、query フィールドのコメント、または extended_info->>'source_query_id' を通じて関連付けられます。
SELECT query_id,
extended_info->>'src_query_id' as "source query id",
application_name,
status,
duration
FROM hologres.hg_query_log
WHERE query_start >= now() - interval '1 hour'
AND application_name IN ('AutoAnalyze', 'Hologres SQL Generated BY AUTO ANALYZE')
ORDER BY query_start DESC
LIMIT 2;
query_id | source query id | application_name | status | duration
---------------------+---------------------+----------------------------------------+---------+----------
1004019226350863009 | 1004019226350778807 | Hologres SQL Generated BY AUTO ANALYZE | SUCCESS | 119
1004019226350778807 | | AutoAnalyze | SUCCESS | 3276
クエリ例
-
最近の AUTO ANALYZE 実行レコードを確認
SELECT usename,
status,
duration,
query_start,
query_end,
query,
application_name
FROM hologres.hg_query_log
WHERE query_start >= now() - interval '1 hour'
AND application_name IN ('AutoAnalyze')
ORDER BY query_start DESC
LIMIT 20;
query_id,
extended_info->>'src_query_id' as "source query id"
-
特定のテーブルの AUTO ANALYZE 実行履歴を確認
SELECT status,
duration,
query_start,
query
FROM hologres.hg_query_log
WHERE query_start >= now() - interval '1 day'
AND application_name IN ('AutoAnalyze')
AND query LIKE '%my_table_name%'
ORDER BY query_start DESC;
-
過去 3 日間の AUTO ANALYZE 実行概要をサマリー
SELECT query_date,
status,
COUNT(*) AS task_count,
AVG(duration) AS avg_duration_ms,
MAX(duration) AS max_duration_ms
FROM hologres.hg_query_log
WHERE query_start >= CURRENT_DATE::timestamptz - interval '2 day'
AND application_name IN ('AutoAnalyze')
AND command_tag = 'ANALYZE'
AND (status = 'SUCCESS' OR (
message NOT LIKE '%does not exist%'
AND message NOT LIKE '%retry later%'))
GROUP BY query_date, status
ORDER BY query_date DESC;
-
過去 1 日間の失敗した AUTO ANALYZE タスクを確認
SELECT query_start,
duration,
message,
query
FROM hologres.hg_query_log
WHERE query_start >= now() - interval '1 day'
AND application_name IN ('AutoAnalyze', 'Hologres SQL Generated BY AUTO ANALYZE')
AND status != 'SUCCESS'
AND (message NOT LIKE '%does not exist%'
AND message NOT LIKE '%retry later%')
ORDER BY query_start DESC;
注意事項
-
AUTO ANALYZE 接続は内部管理者 ID で開始されるため、一般ユーザは完全な AUTO ANALYZE 実行レコードを確認するには
pg_read_all_statsロールまたはデータベース管理者権限が必要です。 -
クエリログに長期間 AUTO ANALYZE レコードが見つからない場合は、AUTO ANALYZE スイッチが有効になっているかどうかを確認することを推奨します。
統計情報の確認およびトラブルシューティング
テーブル統計情報の確認(hologres_statistic.hg_table_statistic)
テーブル統計情報は hologres_statistic.hg_table_statistic テーブルに保存され、システムテーブルでも確認できます。
-
このテーブルをクエリして、最新の ANALYZE からの統計情報を取得します。
SELECT schema_name, -- テーブルスキーマ
table_name, -- テーブル名
user_name, -- 最後に ANALYZE を実行したユーザー
schema_version, -- 前回 ANALYZE 時のテーブルスキーマバージョン
total_rows, -- 前回 ANALYZE 時の行数
sample_rows, -- 前回 ANALYZE 時のサンプル行数
analyze_timestamp, -- 前回 ANALYZE の完了時間
analyze_count -- これまでの ANALYZE 実行回数
FROM hologres_statistic.hg_table_statistic
WHERE unique_name = hologres.hg_internal_statistic_unique_name ('schemaname', 'tablename')
ORDER BY analyze_timestamp DESC;
-- 出力例
schema_name | table_name | user_name | schema_version | total_rows | sample_rows | analyze_timestamp | analyze_count
-------------+------------+------------------+----------------+------------+-------------+---------------------+---------------
public | test_fnr | BASIC$test_fnr | -1 | 999 | 999 | 2026-03-02 22:05:29 | 2
(1 row)
V3.1 以前:
-
各テーブルは hologres_statistic.hg_table_statistic テーブルに 0 ~ n 件のレコードを持ちます。0 件の場合は ANALYZE が一度も実行されておらず、1 件以上ある場合は ANALYZE が実行されています。
-
2 件以上のレコードがある場合、2 つのレコードの schema_version は必ず異なります。テーブルスキーマの変更(ADD COLUMN、CALL SET_TABLE_PROPERTY など)により新しいバージョンが生成され、新しい統計情報レコードが追加されるためです。古い schema_version に対応するレコードは使用されなくなります。
-
以下のクエリ結果例では、同じテーブルに 2 件のレコードがあり、2 番目のレコードの schema_version が最初のレコードよりも低いです。したがって、2 番目のレコードは無効であり使用されません。ユーザーはこれを気にする必要はありません。Hologres は現在、hg_table_statistic テーブル内の履歴期限切れレコードをクリーンアップしていませんが、ユーザーは古いデータを心配する必要はありません。
schema_name | table_name | user_name | schema_version | total_rows | sample_rows | analyze_timestamp | analyze_count
-------------+------------+------------------+----------------+------------+-------------+---------------------+---------------
public | test_fnr | BASIC$test_fnr | 13 | 999 | 999 | 2026-03-01 18:05:29 | 2
public | test_fnr | BASIC$test_fnr | 12 | 999 | 999 | 2026-03-01 08:05:29 | 1
(1 row)
V3.1 以降:
-
各テーブルは hologres_statistic.hg_table_statistic テーブルに 0 ~ 1 件のレコードを持ちます。0 件の場合は ANALYZE が一度も実行されておらず、1 件ある場合は ANALYZE が実行されています。
-
schema_version は一律 -1(非推奨を表す)に設定されます。
-
これは、多くの DDL 操作が統計情報を無効化しなくなったことを意味します。例えば、CALL SET_TABLE_PROPERTY は AUTO ANALYZE を再トリガーせず、既存の統計情報が引き続き使用されます。Hologres V3.0 以前と比較して、AUTO ANALYZE のトリガー頻度が大幅に減少しています。
-
行数およびその他の統計情報のクエリ
行数情報は pg_class テーブルの reltuples フィールドに記録されます。
-- relallvisible > 0:テーブルに行数統計情報あり
-- relallvisible = 0:行数不明。reltuples に依存しないでください。
-- relallvisible < 0:テーブルに統計情報なし
SELECT relallvisible, reltuples FROM pg_class WHERE relname = 'test_table';
テーブルに統計情報がない場合は、以下の「統計情報が欠落しているテーブルの確認」セクションを参照して原因を特定してください。
-
列統計情報のクエリ
pg_stats ビューをクエリすることで、現在のテーブルのすべての列の統計情報を取得できます。例えば、test_table の ds 列の統計情報を取得するには:
select * from pg_stats where tablename = 'test_table' and attname = 'ds';
schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram
------------+------------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------
public | test_table | ds | f | 0 | 4 | 1 | {20241104} | {1} | | | | |
(1 row)
列に統計情報がない場合は、以下の「統計情報が欠落しているテーブルの確認」セクションを参照して原因を特定してください。
統計情報が欠落しているテーブルの確認
Hologres は、現在のデータベースで統計情報が欠落しているテーブルをチェックするためのビュー HG_STATS_MISSING(実際のビュー名はバージョンによって異なる場合があります)を提供しています。これにより、補足 ANALYZE が必要なオブジェクトを簡単に識別できます。
具体的なフィールドおよび使用方法については、対応するインスタンスのドキュメントまたはコンソールヘルプをご参照ください。
一般的な問題およびトラブルシューティング
-
hologres_statistic.hg_table_statistic テーブルから 0 件のレコードが返される可能性のある理由:
-
ANALYZE が一度も実行されていない(手動でも AUTO ANALYZE でも)。
-
AUTO ANALYZE が動作していない、またはテーブルがトリガー条件を満たしていない。
推奨アクション:
-
まず、手動で実行します。
ANALYZE schema_name.table_name;
-
テーブルが長期間 AUTO ANALYZE の対象にならない場合は、AUTO ANALYZE スイッチおよび GUC 構成を確認するか、テクニカルサポートに連絡することを推奨します。
-
analyze_timestamp が明らかに古くなっている可能性のある理由:
-
AUTO ANALYZE が無効化または制限されている(例:
autovacuum_enabled = false)。 -
AUTO ANALYZE のリソースが不足している、または失敗している(ログ/モニタリングと連携して調査可能)。
推奨アクション:
-
手動で ANALYZE を一度実行し、結果を観察します。
-
以下を確認します。
-
hg_enable_start_auto_analyze_workerが有効かどうか。 -
autovacuum_enabled = falseが誤って設定されていないか、または関連する GUC 制限が厳しすぎないか。 -
クエリログに AUTO ANALYZE タスクに関連するエラーがないか。
-
-
クエリプランにおける行数推定が異常(著しく小さすぎるまたは大きすぎる)
-
対応するテーブルに統計情報が欠落している、または統計情報が古くなっていないか確認します。
-
述語列に統計情報があるか確認し(pg_stats)、重要な列に対して列レベルの ANALYZE を実行します。
-
高速行数推定機能が無効化または有効化されていないか確認します。
-
パーティションテーブルの親子統計情報の不整合、または親テーブルの統計情報欠落
-
症状:
hologres_statistic.hg_table_statisticにパーティション親テーブルのレコードがない、またはtotal_rowsがすべての子テーブルの行数合計よりも著しく少ない、または親テーブルのパーティション列統計情報 MCV 分布が古くなっている(例:pg_stats の ds 列に昨日の分布が欠落している)。 -
トラブルシューティングポイント:
-
増分パーティションの ANALYZE / AUTO ANALYZE が無効になっているかどうかを確認します。
-
SHOW hg_experimental_enable_incremental_analyze;
SHOW hg_experimental_enable_incremental_auto_analyze;
-
HG_STATS_MISSINGビューを使用して、マージ不可の子テーブルがないか確認します。 -
クエリログに AUTO ANALYZE タスクに関連するエラーがないか確認します。
-
統計情報が欠落している子テーブルに対して手動で
ANALYZE child_table;を実行するか、オフピーク時間帯に親テーブルに対してANALYZE partition_parent_table;を実行して、システムに統計情報を補完およびマージさせます。
-
pg_stats に特定の列の統計情報がない
-
症状:テーブルには列がありますが、
pg_statsビューで対応する列統計情報が見つかりません。 -
トラブルシューティングポイント:
-
列属性を通じて統計情報が無効化されていないか確認します(
enable_analyze = falseまたはenable_auto_analyze = false)。
-
SELECT attoptions
FROM pg_attribute
WHERE attrelid = 'tablename'::regclass::oid
AND attname = 'columnname';
-[ RECORD 1 ]----------------------
attoptions | {enable_analyze=false}
-
列が ANALYZE(手動または AUTO ANALYZE)に参加しているか確認します。必要に応じて、列レベルの
ANALYZE table_name(col_name);を実行します。
SELECT query_id,
application_name,
status,
query_start,
query
FROM hologres.hg_query_log
WHERE query_start >= now() - interval '1 hour'
AND application_name IN ('Hologres SQL Generated BY ANALYZE', 'Hologres SQL Generated BY AUTO ANALYZE')
AND query like '%tablename%'
ORDER BY query_start DESC
LIMIT 2;
-
列が特殊な型(
bytea、jsonb)かどうか確認します。 -
テーブルが AUTO ANALYZE を実行したにもかかわらず列に統計情報がない場合は、AUTO ANALYZE タスクが異常終了していないか検討します。例えば、
hologres.hg_query_logの AUTO ANALYZE タスクの実行時間が >= 3600000 である場合、このケースでは行数情報のみが収集され、列統計情報は収集されません。
-
AUTO ANALYZE が実行されたがクエリプランが著しく改善されない
-
症状:
hologres.hg_query_logで特定のテーブルの AUTO ANALYZE レコードが確認できるが、実際のクエリプランでは依然として明らかに不合理な行数推定または結合順序が使用されている。 -
トラブルシューティングポイント:
-
AUTO ANALYZE がタイムアウトしていないか確認します。
auto_analyze_work_statement_timeoutのデフォルトは 1 時間であるため、hologres.hg_query_logの AUTO ANALYZE タスクの実行時間が >= 3600 秒の場合、このケースでは行数情報のみが収集され、列統計情報は収集されません。 -
ヒント、固定結合順序、またはレガシーなセッションレベル GUC(例:
enable_nestloopなど)がオプティマイザーの選択を妨害していないか確認します。 -
重要なテーブル/列に対して手動で
ANALYZEを実行し、その後クエリを再実行します。それでも改善されない場合は、クエリログ、FE ログと連携してさらに調査するか、テクニカルサポートに報告することを推奨します。
-
-
統計情報に起因する OOM / メモリ制限超過の問題
-
症状:複雑な複数テーブル結合でエラー
Query executor exceeded total memory limitation ...が発生する、またはプランが極めて不合理な結合戦略(例:大規模テーブルが大規模テーブルをドライブするネステッドループなど)を選択する。 -
トラブルシューティングポイント:
-
関連テーブルに統計情報が欠落している、または著しく古くなっていないか確認します(
hg_table_statisticのレコードおよび AUTO ANALYZE 実行レコードを組み合わせて)。 -
結合列およびフィルター列に対して列レベルの
ANALYZEを実行します。必要に応じて、サンプリング精度を上げるか、高速行数推定機能を有効化します。 -
特定の極端なデータ分布またはピークシナリオでのみ問題が発生する場合は、テクニカルサポートに相談し、統計情報モデルまたは関連 GUC(AUTO ANALYZE しきい値、メモリ制限など)の調整が必要かどうかを評価します。
-
サーバーレス環境での ANALYZE および AUTO ANALYZE の実行
Hologres V3.1 以降、サーバーレスインスタンスまたはサーバーレスコンピューティングリソースが有効化されたインスタンスでは、ANALYZE および AUTO ANALYZE をサーバーレスリソース上で実行することで、インスタンス自体の CPU/メモリ負荷を軽減できます。
このセクションでは、サーバーレスコンピューティングシナリオにおける手動 ANALYZE および AUTO ANALYZE の典型的な動作と推奨構成を、関連する GUC とともに説明します。
手動 ANALYZE およびサーバーレスコンピューティング
-
hg_serverless_computing_enable_analyze_statement-
説明:手動の
ANALYZE文をサーバーレスタスクを通じて実行できるかどうかを制御します。 -
動作:
-
on(デフォルト)に設定すると、システムは ANALYZE 文をサーバーレスコンピューティングリソースにオフロードして実行を許可し、統計情報タスクがインスタンス自体に与える影響を最小限に抑えます。 -
offに設定すると、ANALYZE はローカルインスタンスリソース上で実行されます。
-
-
典型的な推奨事項:
-
サーバーレスインスタンスでは、デフォルトで
onとなっており、統計情報タスクはサーバーレスリソースのみで完了します。 -
トラブルシューティング時またはリソース使用量に特別な要件がある場合、一時的に
offに設定して、明示的にローカルリソース上で ANALYZE を実行できます。
-
-
AUTO ANALYZE およびサーバーレスコンピューティング
AUTO ANALYZE タスクを生成する際、システムは以下の GUC に基づいて、サーバーレスリソースを使用するかどうか、およびサーバーレスタスクの動作をどのように制御するかを決定します。
-
hg_auto_analyze_run_with_serverless_computing-
説明:AUTO ANALYZE タスクをサーバーレスコンピューティングリソースを通じて実行するかどうか。通常のインスタンスではデフォルトで
off、サーバーレスインスタンスではデフォルトでonです。 -
動作:
-
onに設定すると、AUTO ANALYZE タスクはサンプリング計算をサーバーレスリソースプールに送信します。 -
offに設定すると、AUTO ANALYZE は引き続きローカルインスタンスリソースを通じて統計情報を完了します。
-
-
-- データベースレベルで設定
ALTER DATABASE datname SET hg_auto_analyze_run_with_serverless_computing = on;
-
hg_auto_analyze_serverless_computing_query_priority-
説明:サーバーレス AUTO ANALYZE タスクの優先度(
1~5)。値が大きいほど優先度が高くなります。デフォルトは2です。 -
動作:
-
サーバーレス AUTO ANALYZE が有効な場合、システムは各統計情報タスクに対して
SET hg_experimental_serverless_tasks_query_priority = <value>;を通じて対応する優先度を設定します。 -
これは、他のサーバーレスタスク(ETL やオフラインクエリなど)とリソースプールを共有する際に、統計情報タスクの全体キューにおけるプリエンプション能力を制御するのに適用されます。
-
-
推奨事項:
-
本番環境では、通常は中程度の優先度(デフォルトの
2または適度に3に増加)を維持し、コア業務ジョブと過度にリソースを競合しないようにします。 -
統計情報の適時性スコアが極めて高く、サーバーレスリソースが十分にあるシナリオでは、優先度を適宜上げることができます。
-
-
-
hg_auto_analyze_serverless_computing_enable_persisted_snapshot-
説明:サーバーレス AUTO ANALYZE タスクで永続化スナップショット(
persisted snapshot)を使用するかどうか、つまりSET hg_experimental_enable_persisted_snapshot = on/off;を通じて追加のフラッシュをスキップするかどうかを制御します。 -
通常のインスタンスではデフォルトで
off、サーバーレスインスタンスではデフォルトでonです。 -
動作:
-
onに設定すると、統計情報タスクは永続化スナップショットを再利用しようとし、フラッシュをトリガーする必要を減らします。これは高頻度統計情報または多数のパーティションテーブルがあるシナリオにより適しています。 -
offに設定すると、統計情報タスクはより最新のスナップショットを使用しようとし、一貫性または特定のバージョン隔離の要件が高いシナリオに適しています。
-
-
推奨事項:
-
特に必要がない限り、調整しないでください。
-
-
サーバーレスコンピューティングシナリオの使用推奨事項
-
重い ANALYZE タスクの処理にはサーバーレスコンピューティングを優先的に使用
-
データ量が非常に大きいテーブルまたは外部テーブルに対して ANALYZE を実行する際は、以下を有効化することを推奨します。
-
手動 ANALYZE:
set hg_computing_resource = 'serverless'; ANALYZE my_table; -
AUTO ANALYZE:
ALTER DATABASE mydb SET hg_auto_analyze_run_with_serverless_computing = on;
-
-
これにより、統計情報計算の負荷がサーバーレスリソースプールに移行され、インスタンス上のオンラインクエリへの干渉が軽減されます。
-
-
業務重要度に基づいてサーバーレス AUTO ANALYZE タスクの優先度を設定
-
サーバーレスインスタンスでは、統計情報の適時性スコアに敏感で最新の統計情報に依存する重要な業務データベースについて、
hg_auto_analyze_serverless_computing_query_priorityを適宜上げることができます。 -
通常のインスタンスでは、ローカルリソースを使用した AUTO ANALYZE で通常十分です。
-
-
パラメーター調整前に「小規模試験」の原則に従う
-
サーバーレスコンピューティング関連の GUC も高度なパラメーターです。調整前に、テスト環境またはステージング環境でまず検証することを推奨します。
-
サーバーレスリソースプール内の統計情報タスクのキューイングおよび実行時間を観察します。
-
コア業務クエリのレイテンシおよびリソース使用量への影響をモニタリングします。
-
-
重大な副作用がないことを確認した後、データベース単位または段階的に本番環境に展開します。
-