未使用のAI検索エンドポイントを特定する
このページでは、監査ログシステムテーブルを使用して、インデックスを持つもののクエリトラフィックがないAI Searchエンドポイントを見つける方法について説明します。未使用のエンドポイントは、価値を提供することなくリソースを消費し、コストが発生します。未使用のエンドポイントを特定することで、未使用のリソースを整理し、コストを削減するのに役立ちます。
要件
- Unity Catalog が有効になっているワークスペース
system.access.auditテーブルへのアクセス。デフォルトでは、アカウント管理者のみがアクセスできます。他のユーザーにアクセスを付与するには、監査ログ システムテーブルリファレンスを参照してください。- クエリを実行するためのSQLウェアハウスまたはサーバレスコンピュート
仕組み
system.access.audit テーブルは、AI Search API の各呼び出しを service_name = 'vectorSearch' 付きのイベントとしてログに記録します。これには、インデックスの作成、削除、クエリ、アップサート、およびスキャンが含まれます。
1つのエンドポイントは、複数のインデックスを提供できます。未使用のエンドポイントを見つけるには、既存の(作成済みで削除されていない)インデックスのセットを、特定の時間枠でクエリトラフィックを受信したインデックスのセットと比較し、その後、エンドポイントレベルで集計します。エンドポイントは、そのインデックスのいずれもクエリを受信しなかった場合に限り、使用されません。
監査ログには365日分のデータが保持されるため、最長1年間遡って確認することができます。
監査ログは、エンドポイントレベルではなく、インデックスレベルでクエリを記録します。このガイドのクエリは、インデックス作成時に記録された(endpoint_name)を使用して、インデックスをエンドポイントにマッピングします。
未使用のエンドポイントを探す
次のクエリーは、過去 30 日間でどのインデックスもクエリーを受け取らなかったエンドポイントを特定します。監査ログイベントを使用して、どのインデックスが作成され、どのインデックスが削除され、どのインデックスがクエリトラフィックを受信したかを判断し、エンドポイントレベルに集計します。
このクエリは、監査ログ内の createVectorIndex イベントと deleteVectorIndex イベントを比較することで、アクティブなインデックスを特定します。インデックスが365日以上前 (監査ログ保持ウィンドウより前) に作成された場合、結果には表示されません。全体像を把握するには、これらの結果を AI Search 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',
'queryVectorIndexRouteOptimized',
'scanVectorIndex',
'scanVectorIndexRouteOptimized'
)
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',
'queryVectorIndexRouteOptimized',
'scanVectorIndex',
'scanVectorIndexRouteOptimized'
)
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',
'queryVectorIndexRouteOptimized',
'scanVectorIndex',
'scanVectorIndexRouteOptimized'
)
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 共通テーブル式内の INTERVAL 30 DAYS をお好みのウィンドウに置き換えます。
次のステップ
- 定期的なレポートを取得するには、これらのクエリをLakeflowジョブを使用して定期的なジョブとしてスケジュールしてください。
- 追加のコスト最適化戦略については、AI検索のコスト管理ガイドをご確認ください。
- AI検索のコストを監視するために使用ポリシーをセットアップします。AI検索使用ポリシーをご覧ください。