CloudTrail Lake クエリを最適化する - AWS CloudTrail

CloudTrail Lake クエリを最適化する

このページでは、CloudTrail Lake クエリを最適化してパフォーマンスと信頼性を向上させる方法に関するガイダンスを提供します。特定の最適化手法と、一般的なクエリ障害の回避策について説明します。

クエリを最適化するための推奨事項

このセクションの推奨事項に従って、クエリを最適化します。

集計を最適化する

GROUP BY 句で冗長列を除外すると、少ない列では必要なメモリが少なくなるため、パフォーマンスが向上します。例えば、次のクエリでは、eventType のような冗長列で arbitrary 関数を使用してパフォーマンスを向上させることができます。eventTypearbitrary 関数は、値が同じであり、GROUP BY 句に含める必要がないため、 グループからランダムにフィールド値を選択するために使用されます。

SELECT eventName, eventSource, arbitrary(eventType), count(*) FROM $EDS_ID GROUP BY eventName, eventSource

GROUP BY 内のフィールドのリストを一意の値カウント (カーディナリティ) の降順で並べ替えることで、GROUP BY 関数のパフォーマンスを向上させることができます。例えば、各 AWS リージョン で 1 つのタイプのイベント数を取得しながら、awsRegion の一意の値よりも多くの一意の eventName の値があるため、awsRegioneventName ではなく GROUP BY 関数でeventNameawsRegion 順を使用して、パフォーマンスを向上させることができます。

SELECT eventName, awsRegion, count(*) FROM $EDS_ID GROUP BY eventName, awsRegion

近似手法を使用する

重複しない値をカウントするために正確な値が不要な場合は、近似集計関数を使用して最も頻繁な値を見つけます。例えば、approx_distinctCOUNT(DISTINCT fieldName) オペレーションよりはるかに少ないメモリを使用し、より速く実行されます。

クエリ結果を制限する

クエリにサンプルレスポンスのみが必要な場合は、LIMIT 条件を使用して結果を少数の行に制限します。そうしないと、クエリは大きな結果を返し、クエリの実行により多くの時間がかかります。

LIMITORDER BY とともに使用すると、ソートに必要なメモリ量と所要時間が減るため、上位または下位の N レコードの結果をより速く提供することができます。

SELECT * FROM $EDS_ID ORDER BY eventTime LIMIT 100;

LIKE クエリを最適化する

LIKE を使用して一致する文字列を検索できますが、文字列が長い場合は計算量が多くなります。ほとんどの場合、regexp_like 関数はより高速な代替手段です。

多くの場合、探している部分文字列を固定することで検索を最適化できます。例えば、プレフィックスを探している場合は、LIKE 演算子では「%substr%」の代わりに「substr%」を使用し、regexp_like 関数では「^substr」を使用することをお勧めします。

UNION の代わりに UNION ALL を使用する

UNION ALL と UNION は、2 つのクエリの結果を 1 つの結果にまとめる 2 つの方法ですが、UNION は、重複を削除します。UNION ではすべてのレコードを処理して重複を見つける必要があり、メモリと計算を大量に消費しますが、UNION ALL は比較的高速なオペレーションです。レコードの重複排除が必要でない限り、UNION ALL はベストパフォーマンスを実現するために使用してください。

必要な列のみを含める

列が必要ではない場合は、クエリに含めないでください。クエリが処理しなければならないデータが少ないほど、実行速度は速くなります。一番外側のクエリで SELECT * を実行するクエリがある場合は、* を必要な列のリストに変更する必要があります。

ORDER BY 句は、クエリの結果をソートされた順序で返します。大量のデータをソートするときに、必要なメモリが利用できない場合、中間ソート結果がディスクに書き込まれ、クエリの実行が遅くなる可能性があります。結果を厳密にソートする必要がない場合は、ORDER BY 句を追加しないでください。また、必ずしも必要ではない場合は、内部クエリへの ORDER BY の追加は避けてください。

ウィンドウ関数の範囲を小さくする

ウィンドウ関数は、結果を計算するために操作したすべてのレコードをメモリに保持します。ウィンドウが非常に大きい場合、ウィンドウ関数のメモリが不足する可能性があります。クエリが使用可能なメモリ制限内で実行されるように、PARTITION BY 句を追加して、ウィンドウ関数が処理するウィンドウのサイズを小さくしてください。

ウィンドウ関数を含むクエリは、ウィンドウ関数なしで書き直せる場合があります。例えば、row_numberrank を使用する代わりに、max_bymin_by などの集計関数を使用できます。

次のクエリは、max_by を使用して各 KMS キーに最近割り当てられたエイリアスを検索します。

SELECT element_at(requestParameters, 'targetKeyId') as keyId, max_by(element_at(requestParameters, 'aliasName'), eventTime) as mostRecentAlias FROM $EDS_ID WHERE eventsource = 'kms.amazonaws.com' AND eventName in ('CreateAlias', 'UpdateAlias') AND eventTime > DATE_ADD('week', -1, CURRENT_TIMESTAMP) GROUP BY element_at(requestParameters, 'targetKeyId')

この場合、max_by 関数はグループ内の最新のイベント時刻を持つレコードのエイリアスを返します。このクエリは、ウィンドウ関数を使用する同等のクエリよりも実行速度が速く、メモリ使用量も少なくて済みます。

クエリの失敗の回避策

このセクションでは、一般的なクエリの失敗の回避策を提供します。

レスポンスが大きすぎるためクエリが失敗する

レスポンスが大きすぎる場合はクエリが失敗することがあり、メッセージ Query response is too large が発生します。これが生じた場合、集計範囲を小さくできます。

array_agg のような集計関数を使用すると、クエリレスポンス内の少なくとも 1 つの行が非常に大きくなり、クエリが失敗する可能性があります。例えば、array_agg(DISTINCT eventName) の代わりに array_agg(eventName) を使用すると、選択した CloudTrail イベントからのイベント名が重複しているため、レスポンスサイズが大幅に増加します。

リソースの枯渇によりクエリが失敗する

結合、集計、ウィンドウ関数などのメモリを大量に消費するオペレーションの実行中に十分なメモリが利用できない場合、中間結果がディスクにスピルされますが、スピルによりクエリの実行が遅くなり、クエリが Query exhausted resources at this scale factor で失敗するのを防ぐには不十分になる可能性があります。これは、クエリを再試行することで修正できます。

上記のエラーがクエリの最適化後も続く場合は、イベントの eventTime を使用してクエリの範囲を絞り込み、元のクエリ時間範囲のより短い間隔でクエリを複数回実行できます。