Hologres は、セッションレベルまたはデータベースレベルでクエリ動作、接続管理、パフォーマンス、セキュリティを制御する GUC (Grand Unified Configuration) パラメータをサポートしています。
制限
GUC パラメータはシステムテーブルには適用されません。
GUC パラメーターリファレンス
パラメーターは機能ごとにグループ化されています。 Level 列は、各パラメーターを設定できる場所を示します:セッション (現在の接続でただちに有効になります) または データベース (再接続後に有効になります)。
自動分析
これらのパラメーターは、統計情報を自動的に収集して実行計画の精度を維持する自動分析機能を制御します。
|
パラメーター |
説明 |
デフォルト |
レベル |
|
|
自動分析を有効または無効にします。 |
|
セッション / データベース |
|
|
Hologres が内部テーブルの変更をチェックし、自動分析をトリガーする間隔です。 |
|
セッション / データベース |
|
|
Hologres が外部テーブルの変更をチェックし、自動分析をトリガーする間隔です。 |
|
セッション / データベース |
|
|
自動分析の実行ごとにサンプリングする行の最大数です。 |
|
セッション / データベース |
|
|
固定 API を介した変更を自動分析が検出するまでの最大遅延時間です。 |
|
セッション / データベース |
MaxCompute 外部テーブルのクエリ
これらのパラメーターは、Hologres が MaxCompute 外部テーブルをクエリする際の動作をチューニングします。 チューニングガイダンスについては、「MaxCompute外部テーブルのクエリパフォーマンスの最適化」をご参照ください。
|
パラメーター |
説明 |
デフォルト |
有効な値 |
レベル |
|
|
クエリごとにヒットするパーティションの最大数です。 値 |
|
|
セッション / データベース |
|
|
MaxCompute テーブルをスキャンする際に、バッチごとにフェッチする行数です。 |
|
— |
セッション / データベース |
|
|
並列読み取りのデータ分割サイズ (MB 単位) です。 過度に大きな値を設定しないでください。 |
|
— |
セッション / データベース |
|
|
クエリ実行の最大並列度 (DOP) です。 |
CPU コア数 (最大 |
— |
セッション / データベース |
|
|
外部テーブルにおける DML 操作の最大並列度 (DOP) です。 |
|
— |
セッション / データベース |
|
|
Hologres ネイティブリーダーによる MaxCompute ORC ファイルの読み取りを有効にします。 |
|
— |
セッション / データベース |
結果キャッシュ
|
パラメーター |
説明 |
デフォルト |
レベル |
|
|
同一クエリの結果キャッシュを有効にします。 古いキャッシュ結果が問題を引き起こす場合にのみ、無効にしてください。 |
|
セッション / データベース |
内部テーブルクエリの最適化
これらのパラメーターは、内部テーブルのクエリオプティマイザをチューニングします。 詳細については、「クエリパフォーマンスの最適化」をご参照ください。
|
パラメーター |
説明 |
デフォルト |
レベル |
|
|
オプティマイザによる最適な結合順序の検索方法を制御します。 クエリで指定した順序を使用するには、 |
|
セッション |
|
|
多段階集計を強制します。 高カーディナリティの |
|
セッション |
セキュリティと暗号化
|
パラメーター |
説明 |
デフォルト |
レベル |
|
|
データマスキング を有効にします。 設定がすべてのセッションに適用されるように、データベースレベルで設定します。 |
|
データベース (推奨) |
|
|
保管時のデータ暗号化 を有効にして設定します。 データベースレベルで設定します。 |
|
データベース (推奨) |
クエリと接続のタイムアウト
データベースレベルで idle_session_timeout を設定します。 デフォルト値の 0 は、アイドル接続の自動解放を無効にします。これにより、接続制限を使い果たし、接続リークが発生する可能性があります。
|
パラメーター |
説明 |
デフォルト |
レベル |
|
|
実行時間が指定した期間を超えたアクティブなクエリをキャンセルします。 値はミリ秒単位です。値 |
|
セッション (推奨) |
|
|
オープントランザクション内で、指定した期間を超えてアイドル状態が続いたセッションを終了させます。 値はミリ秒単位です。値 |
|
データベース (推奨) |
|
|
指定した期間を超えて非アクティブだったアイドル接続を解放します。 値はミリ秒単位です。値 |
|
データベース (推奨) |
データ型変換
|
パラメーター |
説明 |
デフォルト |
レベル |
|
|
指定した変換関数 ( |
— |
セッション / データベース |
例: to_char の年範囲を拡張するには、次のようにします。
set hg_experimental_functions_use_pg_implementation = 'to_char';
集計関数
|
パラメーター |
説明 |
デフォルト |
有効な値 |
レベル |
|
|
APPROX_COUNT_DISTINCT 関数の精度 (およびメモリ使用量) を制御します。 値を大きくすると誤差範囲は小さくなりますが、メモリ使用量は増加します。 |
|
|
セッション / データベース |
タイムゾーン
|
パラメーター |
説明 |
デフォルト |
レベル |
|
|
セッションまたはデータベースのタイムゾーンを設定します。 |
|
セッション / データベース |
テーブル操作
|
パラメーター |
説明 |
デフォルト |
レベル |
|
|
有効にすると、CREATE TABLE LIKE はテーブルスキーマとテーブルプロパティ (プライマリキー、インデックス) の両方をコピーします。 無効にすると、スキーマのみをコピーします。 |
|
セッション / データベース |
|
|
バッチに重複するプライマリキー値が含まれている場合に、最初の出現を保持するように INSERT ON CONFLICT の競合解決ポリシーを設定します。 |
|
セッション / データベース |
|
|
バッチに重複するプライマリキー値が含まれている場合に、最後の出現を保持するように INSERT ON CONFLICT の競合解決ポリシーを設定します。 |
|
セッション / データベース |
レプリケーションとモニタリング
|
パラメーター |
説明 |
デフォルト |
レベル |
|
|
シャードレベルレプリケーション を有効にします。 |
|
セッション / データベース |
|
|
クライアントに NOTICE メッセージとしてクエリ ID を表示し、トラブルシューティングのために |
|
セッション / データベース |
GUC パラメーターの現在の値の確認
SHOW を実行して、パラメーターの現在の値またはデフォルト値を確認します。
-- 自動分析が有効かどうかを確認
SHOW hg_enable_start_auto_analyze_worker;
-- MaxCompute のパーティション制限を確認
SHOW hg_foreign_table_max_partition_limit;
-- クエリ ID の表示が有効かどうかを確認
SHOW hg_experimental_display_query_id;
GUC パラメーターの設定
GUC パラメーターは、パラメーターのスコープとユースケースに応じて、セッションレベルまたはデータベースレベルで設定します。すべてのパラメーターをデータベースレベルで設定する必要はありません。
セッションレベル
SET 文は、現在の接続にのみパラメーターを設定します。接続を閉じると、この設定は破棄されます。グローバルではなく、特定のクエリやワークロードにのみ動作を適用したい場合は、セッションレベルで設定してください。
構文:
set <GUC_NAME> = <VALUE>;
例:
-- このセッションで自動分析を有効化します
set hg_enable_start_auto_analyze_worker = on;
-- このセッションで MaxCompute のパーティションヒット数を 1024 に制限します
set hg_foreign_table_max_partition_limit = 1024;
-- このセッションでクエリ ID の表示を有効化します
set hg_experimental_display_query_id = on;
データベースレベル
ALTER DATABASE 文は、データベースレベルでパラメーターを設定します。この変更はインスタンスの再起動なしでデータベース全体に適用されます。新しい値を有効にするには、現在の接続を閉じて再接続する必要があります。それ以降に確立された接続は、このパラメーターを自動的に継承します。新しいデータベースを作成する場合は、その GUC パラメーターを明示的に設定してください。GUC パラメーターは自動的には継承されません。
構文:
alter database <DB_NAME> set <GUC_NAME> = <VALUE>;
例:
-- testdb へのすべての接続で自動分析を有効化します
alter database testdb set hg_enable_start_auto_analyze_worker = on;
-- testdb へのすべての接続で MaxCompute のパーティションヒット数を 1024 に制限します
alter database testdb set hg_foreign_table_max_partition_limit = 1024;
-- データベースへのすべての接続でデータマスキングを有効化します
alter database <DB_NAME> set hg_anon_enable = on;
-- データベースへのすべての接続でデータ暗号化を有効化します
alter database <DB_NAME> set hg_experimental_encryption_options='AES256,623c26ee-xxxx-xxxx-xxxx-91d323cc4855,AliyunHologresEncryptionDefaultRole,187xxxxxxxxxxxxx';
-- 非アクティブ状態が 10 分 (600,000 ms) 続いたアイドル接続を解放します
alter database <DB_NAME> SET idle_session_timeout = 600000;
クエリ ID の取得
クエリ ID は、Hologres の各クエリを一意に識別するもので、スロークエリログ hologres.hg_query_log のプライマリキーの一部です。ステートメントのクエリ ID を取得すると、その実行時間、ステータス、読み取り行数、その他の実行詳細を確認できます。このため、クエリ ID はトラブルシューティングの起点となります。
Hologres は、デフォルトではクライアントにクエリ ID を返しません。hg_experimental_display_query_id を有効にすると、ステートメントの実行時にサーバーが NOTICE メッセージでクエリ ID を返します。
パラメーターの説明
|
項目 |
説明 |
|
パラメーター |
|
|
効果 |
ステートメントの実行時に、NOTICE メッセージとしてクライアントにクエリ ID を返します。 |
|
デフォルト値 |
|
|
有効な値 |
|
|
レベル |
セッションまたはデータベース。 |
|
返却形式 |
|
以下の 2 点にご注意ください:
-
クエリ ID は、結果セットの列としてではなく、NOTICE メッセージとして届きます。クエリ結果を読み取るだけ (たとえば、
fetchall()を使用) では、クエリ ID は取得できません。ドライバーが提供する NOTICE 機能を使用する必要があります。 -
このパラメーターは単一のセッションに適用され、接続が閉じると破棄されるため、新しい接続ごとに再設定する必要があります。この設定は、接続プールの初期化ステップに含めることが特に重要です。詳細については、「接続プール」をご参照ください。
クエリ ID 表示の有効化
-- セッションレベル。ビジネス SQL と一緒に実行します。
set hg_experimental_display_query_id = on;
-- 現在の値を確認します。
SHOW hg_experimental_display_query_id;
-- データベースレベル。新しい接続に適用されます。既存の接続は再度開く必要があります。
alter database <DB_NAME> set hg_experimental_display_query_id = on;クライアントからのクエリ ID の取得
Java (JDBC)
JDBC では、NOTICE メッセージは SQLWarning オブジェクトのチェーンとして届きます。ステートメントの実行後、statement.getWarnings() でチェーンをたどり、そこからクエリ ID を解析します。ResultSet にはクエリ ID は含まれません。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLWarning;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class HologresQueryIdDemo {
// NOTICE メッセージ内の "QueryID: " に一致します。
private static final Pattern QUERY_ID_PATTERN = Pattern.compile(
"query[_ ]?id\\s*(?:is\\b|[=:])?\\s*([0-9a-zA-Z_\\-]{6,})", Pattern.CASE_INSENSITIVE);
public static void main(String[] args) throws Exception {
// ご利用のネットワーク環境 (インターネットまたは VPC) に応じたエンドポイントを使用します。
// コンソールのインスタンス詳細ページで確認できます。
String url = "jdbc:postgresql://<ENDPOINT>:80/<DB_NAME>";
String user = "<ACCESS_KEY_ID>";
String password = "<ACCESS_KEY_SECRET>";
try (Connection conn = DriverManager.getConnection(url, user, password);
Statement stmt = conn.createStatement()) {
// クエリ ID の表示を有効にします。このパラメーターはデフォルトでオフになっており、このセッションにのみ適用されます。
stmt.execute("set hg_experimental_display_query_id = on;");
String sql = "select count(*), sum(id) from holo_query_id_demo;";
// 各クエリ ID が 1 つの SQL ステートメントに対応するように、前のステートメントによって残された警告をクリアします。
stmt.clearWarnings();
boolean hasResultSet = stmt.execute(sql);
// 結果セットを読み取ります。クエリ ID はその一部ではありません。
if (hasResultSet) {
try (ResultSet rs = stmt.getResultSet()) {
while (rs.next()) {
System.out.println("rows : (" + rs.getLong(1) + ", " + rs.getLong(2) + ")");
}
}
}
// NOTICE メッセージは SQLWarning オブジェクトのチェーンとして届きます。チェーンをたどってクエリ ID を解析します。
String queryId = null;
List<String> notices = new ArrayList<>();
for (SQLWarning w = stmt.getWarnings(); w != null; w = w.getNextWarning()) {
notices.add(w.getMessage());
Matcher m = QUERY_ID_PATTERN.matcher(w.getMessage());
if (m.find()) {
queryId = m.group(1);
}
}
System.out.println("query_id : " + queryId);
System.out.println("notices : " + notices);
}
}
} 出力例:
rows : (1000, 500500)
query_id : 1002002606817139331
notices : [One or more columns in the following table(s) do not have statistics: holo_query_id_demo, QueryID: 1002002606817139331]次の点にご注意ください:
-
PreparedStatementも同様に動作します。ステートメントの実行後にpstmt.getWarnings()を呼び出します。 -
各ステートメントの前に
clearWarnings()を呼び出します。そうしないと、同じStatementオブジェクトに警告が蓄積され、どのクエリ ID がどのステートメントに対応するのかを判別できなくなります。 -
NOTICE チェーンには、統計情報がないという警告など、無関係なメッセージが含まれることがあります。解析する際には、
QueryID:というプレフィックスで照合してください。
Python (Psycopg 3)
Hologres は PostgreSQL 11 と互換性があります。pip install "psycopg[binary]" でインストールする Psycopg 3 ドライバーを使用します。conn.add_notice_handler() でコールバックを登録して、NOTICE メッセージを受信します。cur.fetchall() によって返される行には、クエリ ID は含まれません。
import re
import psycopg
NOTICES = []
QUERY_IDS = []
QUERY_ID_PATTERN = re.compile(
r"query[_ ]?id\s*(?:is\b|[=:])?\s*([0-9a-zA-Z_\-]{6,})", re.IGNORECASE
)
def notice_handler(diag):
"""サーバーが送信するすべての NOTICE に対して一度呼び出されます。そこからクエリ ID を解析します。"""
text = diag.message_primary or ""
NOTICES.append(text)
match = QUERY_ID_PATTERN.search(text)
if match:
QUERY_IDS.append(match.group(1))
conn = psycopg.connect(
host="<ENDPOINT>", # コンソールのインスタンス詳細ページで確認できます。
port=80,
dbname="<DB_NAME>",
user="<ACCESS_KEY_ID>",
password="<ACCESS_KEY_SECRET>",
)
conn.autocommit = True
conn.add_notice_handler(notice_handler) # NOTICE コールバックを登録します。
cur = conn.cursor()
# クエリ ID の表示を有効にします。このパラメーターはデフォルトでオフになっており、このセッションにのみ適用されます。
cur.execute("set hg_experimental_display_query_id = on;")
def run_sql(sql, params=None, fetch=True):
"""ステートメントを実行し、(rows, query_id, notices) を返します。結果セットがない場合、rows は None です。"""
NOTICES.clear()
QUERY_IDS.clear()
cur.execute(sql, params)
rows = None
if fetch and cur.description is not None:
rows = cur.fetchall()
query_id = QUERY_IDS[-1] if QUERY_IDS else None
return rows, query_id, list(NOTICES)
# DML ステートメント
sql_insert = "insert into holo_query_id_demo select i, 'v' || i from generate_series(1, 1000) i;"
_, query_id_insert, notices_insert = run_sql(sql_insert, fetch=False)
print("SQL :", sql_insert)
print("query_id :", query_id_insert)
print("notices :", notices_insert)
print()
# クエリステートメント
sql_select = "select count(*), sum(id) from holo_query_id_demo;"
rows_select, query_id_select, notices_select = run_sql(sql_select)
print("SQL :", sql_select)
print("query_id :", query_id_select)
print("rows :", rows_select)
print("notices :", notices_select)出力例。DML ステートメントとクエリステートメントの両方がクエリ ID を返します:
SQL : insert into holo_query_id_demo select i, 'v' || i from generate_series(1, 1000) i;
query_id : 1002002606817130830
notices : ['QueryID: 1002002606817130830']
SQL : select count(*), sum(id) from holo_query_id_demo;
query_id : 1002002606817139331
rows : [(1000, 500500)]
notices : ['One or more columns in the following table(s) do not have statistics: holo_query_id_demo', 'QueryID: 1002002606817139331']接続プール
このパラメーターは単一のセッションに適用されるため、すべての物理接続で設定する必要があります。接続プールを使用する場合は、各クエリの前に設定するのではなく、接続の初期化ステップで設定します。
次の例では、Python の psycopg_pool を使用します:
# まず pip install psycopg_pool を実行します。
from psycopg_pool import ConnectionPool
def configure(conn):
conn.autocommit = True
conn.add_notice_handler(notice_handler)
conn.execute("set hg_experimental_display_query_id = on;")
pool = ConnectionPool(kwargs=CONN_INFO, configure=configure, min_size=1, max_size=4)
with pool.connection() as conn:
conn.execute("select 1;").fetchall()Java の場合は、プールの初期化 SQL を使用して、すべての物理接続でこのパラメーターを有効にします。次の例では、HikariCP と Druid を使用します:
// HikariCP: connectionInitSql は、各物理接続が確立されるときに実行されます。
HikariConfig config = new HikariConfig();
config.setJdbcUrl(url);
config.setUsername(user);
config.setPassword(password);
config.setConnectionInitSql("set hg_experimental_display_query_id = on;");
HikariDataSource dataSource = new HikariDataSource(config);
// Druid: connectionInitSqls は、複数の初期化ステートメントを受け入れます。
DruidDataSource druid = new DruidDataSource();
druid.setUrl(url);
druid.setUsername(user);
druid.setPassword(password);
druid.setConnectionInitSqls(Collections.singletonList("set hg_experimental_display_query_id = on;"));プールから接続を借用した後も、各ステートメントの後に statement.getWarnings() を使用してクエリ ID を取得します。詳細については、「Java (JDBC)」をご参照ください。
クエリ ID による実行詳細の確認
クエリ ID を使用すると、スロークエリログでクエリの実行時間、ステータス、読み取り行数、その他の詳細を特定できます:
select query_id, status, duration, query_start, application_name, command_tag
from hologres.hg_query_log
where query_id = '<QUERY_ID>';hologres.hg_query_log への書き込みには約 1 分の遅延があります。完了したばかりのクエリはまだ表示されない場合があるため、少し待ってから再試行してください。
注意事項
-
このパラメーターは単一のセッションに適用され、接続が閉じると破棄されます。
set hg_experimental_display_query_id = on;を新しい接続ごとに実行してください。そうしないと、その接続でのクエリはクエリ ID を返しません。 -
すべてのステートメントがクエリ ID を返すわけではありません。
CREATE TABLEやDROP TABLEなどの DDL ステートメントや、select 1;のようにコンピュートエンジンに到達しない単純なクエリは、クエリ ID を返しません。これは想定内の動作です。INSERTなどの DML ステートメントや、SELECTなどの通常のクエリはクエリ ID を返します。 -
NOTICE チェーンには、統計情報がないという警告など、他のメッセージが含まれることがあります。誤った値を取得しないように、
QueryID:というプレフィックスで照合してください。
クエリ ID が見つからない場合のトラブルシューティング
次の項目を順番に確認してください:
-
SHOW hg_experimental_display_query_id;を実行して、値がonであることを確認します。offの場合、現在の接続ではステートメントが実行されていません。接続プールを使用している場合、異なる接続が割り当てられた可能性があります。再度設定するか、接続の初期化ロジックを確認してください。 -
NOTICE メッセージが届いたかどうかを確認します。何も届いていない場合、サーバーは何も送信していません。インスタンスのバージョンがこのパラメーターをサポートしていること、およびステートメントの種類がクエリ ID を生成することを確認してください。
-
NOTICE メッセージは届いたがクエリ ID が解析されなかった場合、文言が解析ルールと一致していません。生のメッセージを出力し、インスタンスが返す形式に合わせてルールを調整してください。
-
接続プールを使用している場合は、すべての物理接続に適用されるように、ステートメントが接続の初期化ステップで実行されることを確認してください。