[アップデート] Amazon Redshift クエリパフォーマンスの監視を改善するクエリ識別子を試してみました!
AWS事業本部コンサルティング部の石川です。Amazon Redshiftは、新しい 「クエリ識別子」(query hash) を導入することで、実行したクエリのトレースが容易になり、パフォーマンスの監視が改善されます。
クエリ識別とは
Amazon Redshiftが導入した新機能 「クエリ識別子」(query hash) は、SQLクエリに対して一意の識別子を割り当てる仕組みです。この識別子は、クエリのテキスト表現と述語値に基づいて生成されます。これらの新しい列は、SYS_QUERY_HISTORYビューに追加されました。
クエリ識別子には2種類あります。
-
user_query_hash
- クエリリテラルを含む、クエリから生成されたクエリハッシュ
- 同じクエリテキストで繰り返されるクエリは、同じ user_query_hash 値を持つ
-
generic_query_hash
- クエリリテラルを除いたクエリハッシュ
- 同じクエリテキストで、異なるクエリリテラルを持つ繰り返しクエリは、同じ generic_query_hash 値を持つ
※ クエリリテラルとは、SQLクエリ内で直接指定される固定値のことを指します。
クエリ識別子の導入の利点
クエリ識別子の導入により、以下のような利点があります。
-
長期的なパフォーマンス追跡
- 時間の経過とともにクエリのパフォーマンスを効果的に追跡できる
-
リソース集約型クエリの特定
- 繰り返し発生するリソース集約型クエリのパターンを特定できる
-
トレンド分析
- 一定期間にわたるクエリのトレンド分析を実行できる
-
パフォーマンス比較
- 異なる時間帯におけるクエリのパフォーマンスを比較できる
これらの機能により、Redshiftの管理者やデベロッパーは、クエリのパフォーマンスをより詳細に分析し、最適化の機会を特定することができます。
実際に試すとどうなるのか
クエリ識別子は、SYS_QUERY_HISTORYビューを参照します。
例えば、下記のクエリを順にクエリしたとします。
SELECT * FROM users;
select * from users;
/* xxx */SELECT * FROM users;
SELECT * FROM users_2;
SELECT * FROM users WHERE userid = 1;
SELECT * FROM users WHERE userid = 2;
SYS_QUERY_HISTORYビューで、user_query_hashとgeneric_query_hashを確認したところ以下の結果になりました。
- クエリの結果が同じになりうるSQLは、user_query_hashとgeneric_query_hashが同じになる
- 述語(WHERE句)で指定している値が異なる場合、generic_query_hashは同じ、user_query_hashは違う
dev=# SELECT query_text, query_id, user_query_hash, generic_query_hash, start_time, end_time, execution_time
FROM SYS_QUERY_HISTORY
WHERE start_time > '2024-10-16 11:30:00'
ORDER BY start_time ASC;
-[ RECORD 1 ]-----+------------------------------------------------------------------------------------------
query_text | SELECT * FROM users;
query_id | 2643012
user_query_hash | XTeGWhEP4Q8=
generic_query_hash | XTeGWhEP4Q8=
start_time | 2024-10-16 11:36:05.430334
end_time | 2024-10-16 11:36:10.584294
execution_time | 11641
-[ RECORD 2 ]-----+------------------------------------------------------------------------------------------
query_text | select * from users;
query_id | 2643023
user_query_hash | XTeGWhEP4Q8=
generic_query_hash | XTeGWhEP4Q8=
start_time | 2024-10-16 11:36:21.260424
end_time | 2024-10-16 11:36:21.261632
execution_time | 0
-[ RECORD 3 ]-----+------------------------------------------------------------------------------------------
query_text | /* xxx */SELECT * FROM users;
query_id | 2643041
user_query_hash | XTeGWhEP4Q8=
generic_query_hash | XTeGWhEP4Q8=
start_time | 2024-10-16 11:36:31.233777
end_time | 2024-10-16 11:36:31.234903
execution_time | 0
-[ RECORD 4 ]------+-----------------------------------------------------------------------------------------
query_text | SELECT * FROM users_2;
query_id | 2643055
user_query_hash | AEos8XsWPvk=
generic_query_hash | AEos8XsWPvk=
start_time | 2024-10-16 11:36:52.58272
end_time | 2024-10-16 11:36:53.007361
execution_time | 41223
-[ RECORD 5 ]------+-----------------------------------------------------------------------------------------
query_text | SELECT * FROM users WHERE userid = 1;
query_id | 2643986
user_query_hash | ISJxUdGk8ZI=
generic_query_hash | X5iKMHinTRE=
start_time | 2024-10-16 12:07:24.971219
end_time | 2024-10-16 12:07:28.349283
execution_time | 7948
-[ RECORD 6 ]------+-----------------------------------------------------------------------------------------
query_text | SELECT * FROM users WHERE userid = 2;
query_id | 2644003
user_query_hash | VG0HWgTqr/M=
generic_query_hash | X5iKMHinTRE=
start_time | 2024-10-16 12:07:34.910264
end_time | 2024-10-16 12:07:35.002553
execution_time | 2959
user_query_hashとgeneric_query_hashを比較することで、同じ構造を持つが異なるパラメータを使用するクエリを特定できます。これにより、パラメータ化されたクエリのパフォーマンスを分析したり、特定のパラメータ値が性能に与える影響を調査したりすることが可能になります。
最後に
かなり前に、Amazon Redshift クエリ履歴に任意のコメントを追加する方法というブログの中で、任意の識別子を埋め込んで、クエリを特定できる方法をご紹介しました。今回のアップデートで、Redashiftがクエリのハッシュをシステムテーブルに自動保存するのでこのような手間を取らなくても済むようになりました。
実際に検証した結果を踏まえると、これまでも内部的にこれらの情報に基づいて、クエリの結果キャッシュやコンパイルキャッシュの判定に用いられていたのではないかと類推します。
Amazon Redshiftのクエリ識別子は、性能監視と最適化に新たな次元をもたらします。この機能は、Amazon Redshift Provisioned とAmazon Redshift Serverlessの両方で利用可能です。
Redshiftの管理者やデベロッパーは、この新機能を活用してクエリのパフォーマンスを詳細に分析し、最適化の機会を特定することができます。クエリ識別子を使用することで、長期的なパフォーマンストレンドの把握や、リソース集約型クエリの特定が容易になり、結果としてRedshiftの全体的な性能と効率性の向上につながることが期待されます。