未使用のベクトル検索エンドポイントを特定する
このページでは、監査ログ システム テーブルを使用して、インデックスはあるがクエリ トラフィックを受信していない待機検索エンドポイントを見つける方法について説明します。 使用されていないエンドポイントは、価値を生み出すことなくリソースを消費し、コストを発生させる。未使用のエンドポイントを特定することで、未使用のリソースを整理し、コストを削減できます。
要件
- Unityカタログ対応のワークスペース。
system.access.auditテーブルへのアクセス。デフォルトでは、アカウント管理者のみがアクセスできます。他のユーザーにアクセス権を付与するには、 「監査ログシステムテーブルのリファレンス」を参照してください。- クエリを実行するためのSQLまたはサーバーレス コンピュート。
仕組み
system.access.auditテーブルは、すべてのベクトル検索 API 呼び出しをservice_name = 'vectorSearch'のイベントとしてログに記録します。これには、インデックスの作成、削除、クエリ、アップサート、スキャンが含まれます。
単一のエンドポイントで複数のインデックスを処理できます。未使用のエンドポイントを見つけるには、存在するインデックス(作成されたが削除されていないインデックス)のセットと、指定された時間枠内でクエリトラフィックを受信したインデックスのセットを比較し、エンドポイントレベルで集計します。エンドポイントは、そのインデックスの いずれ にもクエリが送信されなかった場合にのみ、未使用とみなされます。
監査ログには365日分のデータが保存されるため、最大1年前までさかのぼって確認できます。
監査ログには、エンドポイントレベルではなく、インデックスレベルでのクエリが記録されます。このガイドのクエリは、インデックス作成時に記録されたendpoint_nameを使用して、インデックスをエンドポイントにマッピングします。
未使用のエンドポイントを見つける
以下のクエリは、過去30日間にどのインデックスもクエリを受信していないエンドポイントを特定します。監査ログイベントを使用して、どのインデックスが作成され、どのインデックスが削除され、どのインデックスがクエリトラフィックを受信したかを判断し、エンドポイントレベルに集約します。
このクエリは、監査ログ内のイベントcreateVectorIndexとdeleteVectorIndexを比較することで、アクティブなインデックスを特定します。インデックスが365日以上前(監査ログの保持期間前)に作成された場合、結果には表示されません。全体像を把握するには、これらの結果をベクトル検索list_indexes SDKメソッドの出力と相互参照してください。
WITH created_indexes AS (
-- All indexes created in the last year
SELECT DISTINCT
request_params['name'] AS index_name,
request_params['endpoint_name'] AS endpoint_name
FROM system.access.audit
WHERE service_name = 'vectorSearch'
AND action_name = 'createVectorIndex'
AND event_date >= current_date() - INTERVAL 365 DAYS
),
deleted_indexes AS (
-- Indexes that have been deleted
SELECT DISTINCT
request_params['name'] AS index_name
FROM system.access.audit
WHERE service_name = 'vectorSearch'
AND action_name = 'deleteVectorIndex'
AND event_date >= current_date() - INTERVAL 365 DAYS
),
active_indexes AS (
-- Indexes that exist (created but not deleted)
SELECT ci.index_name, ci.endpoint_name
FROM created_indexes ci
LEFT JOIN deleted_indexes di ON ci.index_name = di.index_name
WHERE di.index_name IS NULL
),
queried_indexes AS (
-- Indexes that received queries in the last 30 days
SELECT DISTINCT
request_params['name'] AS index_name
FROM system.access.audit
WHERE service_name = 'vectorSearch'
AND action_name IN (
'queryVectorIndex',
'queryVectorIndexNextPage',
'scanVectorIndex'
)
AND event_date >= current_date() - INTERVAL 30 DAYS
),
index_status AS (
SELECT
ai.endpoint_name,
ai.index_name,
CASE WHEN qi.index_name IS NOT NULL THEN 1 ELSE 0 END AS is_queried
FROM active_indexes ai
LEFT JOIN queried_indexes qi ON ai.index_name = qi.index_name
)
SELECT
endpoint_name,
COUNT(*) AS total_indexes,
SUM(is_queried) AS queried_indexes,
COUNT(*) - SUM(is_queried) AS unqueried_indexes
FROM index_status
GROUP BY endpoint_name
HAVING SUM(is_queried) = 0 -- Only fully unused endpoints
ORDER BY total_indexes DESC
アクティブなエンドポイント内で未使用のインデックスを検索します
エンドポイントが一部のインデックスに対するクエリを積極的に処理している場合でも、トラフィックを受け取っていないインデックスが存在する可能性があります。これらの未使用のインデックスは、エンドポイント上で依然としてリソースを消費します。アクティブなエンドポイントから未使用のインデックスを削除することで、メモリ使用量を削減し、不必要なスケールアップを防ぐことができます。
以下のクエリは、他のアクティブなインデックスを持つエンドポイント上のインデックスを含め、個々の未使用インデックスを特定します。
WITH created_indexes AS (
SELECT DISTINCT
request_params['name'] AS index_name,
request_params['endpoint_name'] AS endpoint_name
FROM system.access.audit
WHERE service_name = 'vectorSearch'
AND action_name = 'createVectorIndex'
AND event_date >= current_date() - INTERVAL 365 DAYS
),
deleted_indexes AS (
SELECT DISTINCT
request_params['name'] AS index_name
FROM system.access.audit
WHERE service_name = 'vectorSearch'
AND action_name = 'deleteVectorIndex'
AND event_date >= current_date() - INTERVAL 365 DAYS
),
active_indexes AS (
SELECT ci.index_name, ci.endpoint_name
FROM created_indexes ci
LEFT JOIN deleted_indexes di ON ci.index_name = di.index_name
WHERE di.index_name IS NULL
),
queried_indexes AS (
SELECT DISTINCT
request_params['name'] AS index_name
FROM system.access.audit
WHERE service_name = 'vectorSearch'
AND action_name IN (
'queryVectorIndex',
'queryVectorIndexNextPage',
'scanVectorIndex'
)
AND event_date >= current_date() - INTERVAL 30 DAYS
)
SELECT
ai.endpoint_name,
ai.index_name
FROM active_indexes ai
LEFT JOIN queried_indexes qi ON ai.index_name = qi.index_name
WHERE qi.index_name IS NULL
ORDER BY ai.endpoint_name, ai.index_name
インデックスごとのクエリアクティビティの詳細を取得します
未使用のインデックスだけでなく、すべてのインデックスにわたるクエリパターンを把握するには、次のクエリを使用します。このクエリは、各インデックスの最終クエリ時刻とクエリ量を検出し、クエリは行われているもののトラフィックが非常に少ないインデックスを特定するのに役立ちます。これらのインデックスは、クリーンアップの対象となる可能性があります。
SELECT
request_params['name'] AS index_name,
MAX(event_time) AS last_query_time,
DATEDIFF(current_date(), DATE(MAX(event_time))) AS days_since_last_query,
COUNT(*) AS query_count_30d,
COUNT(DISTINCT DATE(event_time)) AS active_days_30d
FROM system.access.audit
WHERE service_name = 'vectorSearch'
AND action_name IN (
'queryVectorIndex',
'queryVectorIndexNextPage',
'scanVectorIndex'
)
AND event_date >= current_date() - INTERVAL 30 DAYS
GROUP BY 1
ORDER BY last_query_time ASC
未使用のエンドポイントを作成した人物を特定する
未使用のインデックスを提供しているエンドポイントを作成したユーザーを特定するには、次のクエリを使用します。これは、清掃作業を行う適切なチームに連絡するのに役立ちます。
SELECT
request_params['name'] AS endpoint_name,
user_identity.email AS created_by,
event_time AS created_at
FROM system.access.audit
WHERE service_name = 'vectorSearch'
AND action_name = 'createEndpoint'
AND event_date >= current_date() - INTERVAL 365 DAYS
ORDER BY event_time DESC
ルックバック期間をカスタマイズする
上記の例では、「未使用」を定義するために30日間の期間を使用しています。使用状況に応じてINTERVAL値を調整してください。
- 30日間 :ほとんどのワークロードにとって適切なデフォルト値です。
- 7日間 :毎日クエリを実行する必要があるワークロードに使用します。
- 90日間 :実行頻度の低いバッチ処理や季節的なワークロードに使用します。
queried_indexes CTE のINTERVAL 30 DAYSを、お好みのウィンドウサイズに置き換えてください。
次のステップ
- LakeFlowジョブを使用してこれらのクエリを定期的なジョブとしてスケジュールし、定期的なレポートを取得します。
- コスト最適化のための追加戦略については、ベクトル検索コスト管理ガイドを参照してください。
- 予算ポリシーを設定して、一括検索コストを監視します。 「節約検索」を参照してください。