Giip AI Harness가 쿼리 힌트(Query Hint)를 배제하는 이유
公開日 2026-09-06 · 更新日 2026-09-06 · 最終検証日 2026-09-06
結論
범용 기반 AI 모델에 슬로우 쿼리 튜닝을 요청하면 FORCE INDEX나 조인 힌트로 즉각적인 속도 개선을 제안하는 경우가 많습니다. 그러나 힌트는 CBO(비용 기반 옵티마이저)가 데이터량과 분포 변화에 맞춰 실행계획을 다시 선택하는 기능을 차단하고, 인덱스 신설·통합·삭제 같은 통상적인 수명주기 작업과 코드를 강하게 결합시킵니다. Giip AI Harness는 이런 이유로 힌트 사용을 원칙적으로 배제하고, 통계 정보 정비와 Sargability(검색 조건이 인덱스를 활용할 수 있는 형태인지) 확보를 통해 CBO의 자율적 판단을 보장하도록 제약합니다.
この文書の適用条件
| 対象製品 | Giip AI Harness(비교 대상: 범용 기반 AI 모델의 SQL 생성) |
|---|---|
| 確認バージョン | 제품 버전에 의존하지 않는 설계 원칙 설명(진단 SQL 예시는 SQL Server 2008 이상 기준) |
| 適用環境 | AWS, Azure, 온프레미스 |
| 必要権限 | 진단 SQL은 VIEW SERVER STATE 등 참조 권한. 코드베이스 검색은 리포지토리 읽기 권한 |
| 実行影響 | 조회 전용(본문 명령은 상태를 변경하지 않음) |
| 再起動 | 불필요 |
| 最終検証日 | 2026-09-06 |
そのまま実行できるコマンド
- 対象
- 애플리케이션·저장 프로시저 소스 코드 리포지토리
- 権限
- 리포지토리 읽기 권한
- 変更作業
- 없음(검색만 수행)
- Production実行
- 해당 없음(로컬 또는 CI에서 실행)
# 대상: 애플리케이션 및 저장 프로시저 소스 코드 리포지토리
# 권한: 리포지토리 읽기 권한
# 변경 작업: 없음(검색만 수행)
# Production 실행: 해당 없음(로컬 또는 CI에서 실행)
# 실행계획을 강제하는 대표적인 패턴을 코드 전체에서 검색한다
# WITH (INDEX(...)) / FORCESEEK / FORCESCAN / 명시적 조인 힌트(LOOP|HASH|MERGE) / OPTION(FORCE ORDER)
grep -RniE "with[[:space:]]*\([[:space:]]*index[[:space:]]*\(|forceseek|forcescan|force[[:space:]]*order|loop[[:space:]]+join|hash[[:space:]]+join|merge[[:space:]]+join" --include=*.sql --include=*.cs --include=*.ts .이 검색은 정규식 기반이므로 히트는 "조사 대상"이지 "확정된 강제 참조"가 아닙니다. 1건씩 실제 구문을 확인한 뒤 판단하세요.
- 対象
- SQL Server 2008 이상 / Amazon RDS for SQL Server / Azure SQL
- 権限
- VIEW DEFINITION
- 変更作業
- 없음(참조만)
- Production実行
- 가능
-- 대상: SQL Server 2008 이상 / Amazon RDS for SQL Server / Azure SQL
-- 권한: VIEW DEFINITION
-- 변경 작업: 없음(참조만)
-- Production 실행: 가능
SELECT
o.name AS object_name,
o.type_desc AS object_type
FROM sys.sql_modules AS m
INNER JOIN sys.objects AS o
ON o.object_id = m.object_id
WHERE m.definition LIKE '%INDEX(%'
OR m.definition LIKE '%FORCESEEK%'
OR m.definition LIKE '%FORCESCAN%'
OR m.definition LIKE '%FORCE ORDER%'
ORDER BY o.name;애플리케이션 리포지토리에 남아 있지 않아도, 저장 프로시저나 뷰 정의 안에 힌트가 남아 있는 경우를 보완적으로 찾기 위한 조회입니다.
- 対象
- SQL Server 2008 이상 / Amazon RDS for SQL Server / Azure SQL Managed Instance
- 権限
- VIEW SERVER STATE(Azure SQL Database는 VIEW DATABASE STATE)
- 変更作業
- 없음(참조만)
- Production実行
- 가능
-- 대상: SQL Server 2008 이상 / Amazon RDS for SQL Server / Azure SQL Managed Instance
-- 권한: VIEW SERVER STATE(Azure SQL Database는 VIEW DATABASE STATE)
-- 변경 작업: 없음(참조만)
-- Production 실행: 가능
SELECT
OBJECT_NAME(i.object_id) AS table_name,
i.name AS index_name,
ius.user_seeks,
ius.user_scans,
ius.user_lookups,
ius.user_updates,
ius.last_user_seek,
ius.last_user_scan,
ius.last_user_lookup
FROM sys.indexes AS i
LEFT JOIN sys.dm_db_index_usage_stats AS ius
ON ius.object_id = i.object_id
AND ius.index_id = i.index_id
AND ius.database_id = DB_ID()
WHERE i.object_id = OBJECT_ID('dbo.SampleTable')
ORDER BY i.name;이 DMV의 카운터는 서비스 재시작·장애조치(failover)·인스턴스 재생성 시 초기화됩니다. 관측 기간이 짧을 뿐인 "사용률 0"을 삭제 근거로 삼지 말고, 반드시 위 1)·2)의 코드 검색 결과와 함께 판단하세요.
結果の読み方
| 列 | 意味 | 確認するポイント |
|---|---|---|
| user_seeks / user_scans / user_lookups | 해당 인덱스가 조회성 작업에서 사용된 누적 횟수 | 모두 0이어도 최근 서비스 재시작·장애조치 이후 기간만 반영됐을 가능성이 있음 |
| user_updates | 쓰기 작업에 따른 인덱스 유지 비용의 누적 횟수 | 조회는 거의 없고 갱신만 많다면 삭제 후보로서의 우선순위가 올라감 |
| last_user_seek / last_user_scan / last_user_lookup | 마지막으로 조회성 작업에 사용된 시각 | NULL이면 DMV 초기화 이후 한 번도 참조되지 않았다는 의미(그 이전 실적은 유실됨) |
こういう状況で使います
- 동일한 기반 AI 모델에 같은 슬로우 쿼리를 넣어도, 사용하는 도구에 따라 제안 내용이 다르다
- AI가 제안한 FORCE INDEX나 조인 힌트를 적용한 직후에는 빨라지지만, 데이터량이 늘어난 몇 달 뒤 CPU·I/O가 급증한다
- 사용률 지표만을 근거로 미사용으로 판단한 인덱스를 삭제했더니, 특정 쿼리·저장 프로시저가 즉시 예외를 일으켰다
- 인덱스를 재설계하거나 DDL을 변경할 때마다 애플리케이션 쪽과의 조율이 필요해 작업이 지연된다
考えられる原因(可能性の高い順)
01
데이터 분포 변화에 따른 선택도(Selectivity)의 역전
동일한 스키마라도 국가, 서비스 성격, 트래픽 유입 경로에 따라 데이터 볼륨과 카디널리티는 달라집니다. 데이터가 적을 때 최적이었던 Index Seek + Key Lookup은, 행 수가 수천만 건 규모로 늘거나 특정 조건에 데이터가 편중(Skew)되면 대량의 랜덤 I/O를 유발합니다. 일정 임계점(Tipping Point)을 넘어서면 Index Scan이나 Clustered Index Scan을 통한 순차 접근이 오히려 더 빠르고 안정적인 경우가 적지 않습니다. 힌트는 이 전환을 CBO가 판단하지 못하도록 고정해 버립니다.
02
인덱스 수명 주기와 애플리케이션 코드의 위험한 결합
대규모 데이터베이스는 복합 인덱스의 신설과, 중복되거나 미사용(Unused)인 인덱스의 정리를 지속적으로 수행합니다. 특정 인덱스를 가리키는 기술이 소스 코드나 저장 프로시저에 하드코딩되어 있으면, 그 인덱스를 변경·삭제하는 순간 운영 환경에서 즉각적인 런타임 예외(인덱스를 찾을 수 없음 등)가 발생합니다. 대규모 서비스 현장에서는, 사용률 지표만으로 미사용 인덱스를 정리했다가 특정 코드·쿼리가 그 인덱스를 강제로 참조하고 있어 즉시 예외가 발생하는 사례가 실무에서 드물지 않습니다.
03
모델의 차이가 아니라 Harness의 차이
범용 파운데이션 모델은 눈앞의 쿼리 텍스트만 보고 국소적 최적화(Local Minima)를 시도합니다. Giip AI Harness는 특정 인덱스를 강제하는 것, 정적인 데이터셋을 전제로 한 튜닝, 인덱스 변경 시 애플리케이션이 깨지는 리스크를 피하기 위해, 힌트를 쓰지 않고 CBO의 판단 여지를 남기는 제약을 AI의 행동 반경(Harness)에 직접 넣어 두고 있습니다.
確認手順
- 1
코드베이스 내 계획 강제 힌트를 전수 검색한다
参照のみ위 grep 패턴으로 애플리케이션과 저장 프로시저 양쪽에서 WITH (INDEX(...)), FORCESEEK/FORCESCAN, 명시적 조인 힌트, FORCE ORDER를 검색합니다.
- 2
인덱스 실사용 통계를 확인한다
参照のみsys.dm_db_index_usage_stats로 조회·갱신 횟수와 마지막 참조 시각을 확인합니다.
- 3
DMV 카운터의 초기화 여부를 확인한다
参照のみ최근 서비스 재시작·장애조치·인스턴스 재생성 시각을 확인하고, 관측 기간이 그 이후로 한정되어 있지 않은지 확인합니다. 관측 기간이 짧으면 "사용률 0"은 판단 근거로 충분하지 않습니다.
- 4
추정 행 수와 실행계획의 선택도를 비교한다
参照のみ실행계획의 추정 행 수와 실제 행 수를 비교해, 데이터 분포 편중에 따른 선택도 역전이 일어나지 않았는지 확인합니다.
- 5
Sargability를 저해하는 요소를 확인한다
参照のみWHERE절의 열에 함수를 적용하거나 암시적 형변환이 발생하는 등, 인덱스를 사용할 수 없게 만드는 작성 방식이 없는지 확인합니다.
対応方法
すぐに実施できる低リスクの対応
기존 쿼리·저장 프로시저에서 계획 강제 힌트를 제거한다
中grep 결과로 발견된 FORCE INDEX·조인 힌트·FORCE ORDER를 영향 범위를 확인하면서 하나씩 제거합니다. 제거 후에는 실행계획을 비교해 예상치 못한 성능 저하가 없는지 확인합니다.
인덱스 삭제 판단 기준에 전수 검색을 포함시킨다
低사용률 통계가 0이라는 사실뿐 아니라, 코드베이스 전수 검색으로 해당 인덱스를 강제 참조하는 곳이 없다는 것을 삭제의 전제 조건으로 삼습니다.
事前検討が必要な変更
통계 정보를 정기적으로 최신화하는 운영 체계를 마련한다
低CBO가 올바른 선택도로 판단할 수 있도록 통계 정보 자동 갱신 설정과 갱신 주기를 재검토합니다.
인덱스 수명 주기 변경과 애플리케이션 배포를 분리한다
中인덱스의 신설·통합·삭제를 애플리케이션 배포 파이프라인과 독립적으로 수행할 수 있는 체계를 만듭니다. 사전에 의존관계 전수 검색을 실시하는 절차를 포함시킵니다.
専門家のレビューが必要な作業
Sargability를 확보하는 형태로 쿼리를 재설계한다
専門家レビュー必須WHERE절의 함수 래핑과 암시적 형변환을 제거하고, 인덱스를 그대로 활용할 수 있는 조건식으로 다시 작성합니다. 영향 범위가 넓다면 전문적인 리뷰를 거치십시오.
스케일아웃·스케일업을 고려한 쿼리 구조를 설계한다
高데이터량이 앞으로 수 배에서 수십 배로 늘어난다는 전제로, 실행계획이 어느 쪽으로 바뀌어도 무너지지 않는 쿼리 구조를 검토합니다.
!注意事項
- sys.dm_db_index_usage_stats의 카운터는 서비스 재시작·장애조치·인스턴스 재생성 시 초기화됩니다. 짧은 관측 기간만으로 "사용되지 않는다"고 판단하지 마십시오.
- 코드베이스 전수 검색은 정규식에 기반하므로, 히트는 "조사 대상"이지 "확정된 강제 참조"가 아닙니다. 하나씩 실제 구문을 확인하십시오.
- 계획 강제 힌트 제거는 실행계획을 변경하는 작업입니다. 운영 환경에 적용하기 전 스테이징 환경에서 제거 전후의 실행계획을 비교하십시오.
- AI가 제안하는 힌트를 포함해, 단발성 쿼리 실행 속도만을 근거로 한 변경은 데이터량이 달라진 이후의 동작을 보장하지 않습니다.
これで解決しない場合に確認すること
삭제 예정 인덱스가 실행계획 캐시에 남아 있지 않은지 확인했는가
sys.dm_exec_query_stats와 sys.dm_exec_sql_text를 함께 사용해, 최근 실행된 쿼리의 실행계획에 해당 인덱스에 대한 참조가 없는지 확인합니다.
동일한 패턴의 힌트가 다른 리포지토리·다른 저장 프로시저 그룹에도 남아 있지 않은지 전수 확인했는가
한 리포지토리에서 발견되지 않았더라도, 다른 배치 처리나 다른 팀이 관리하는 저장 프로시저에 같은 작성 방식이 남아 있을 수 있습니다.
통계 정보의 갱신 시각이 오래되지 않았는지 확인했는가
CBO의 판단은 샘플링된 통계 정보에 기반합니다. 통계가 오래되어 있으면 힌트를 제거해도 CBO가 올바른 선택도로 판단할 수 없습니다.
この文書の根拠と限界
実運用で確認した内容
이 문서는 SQL Server의 공개 DMV·카탈로그 뷰 사양(sys.dm_db_index_usage_stats, sys.sql_modules 등)과, 대규모 서비스 운영에서 일반적으로 관찰되는 경향을 일반화한 서술입니다. 특정 장애 건수·발생 일시·대상 시스템을 특정할 수 있는 정보는 포함하지 않습니다.
よくある質問
쿼리 힌트는 절대 쓰면 안 되나요?
원칙적으로 배제하지만 절대적인 금지는 아닙니다. 옵티마이저의 알려진 결함을 일시적으로 회피해야 하는 경우처럼 매우 예외적인 상황에서는, 영향 범위와 롤백 절차를 명시한 설계 리뷰를 거친 뒤 제한적으로 사용을 검토할 수 있습니다. 일상적인 튜닝 수단으로는 쓰지 않습니다.
같은 기반 AI 모델인데 왜 도구마다 제안 내용이 다른가요?
모델 자체의 능력 차이가 아니라, 모델의 행동 범위를 제약하는 장치(Harness)의 차이입니다. 제약이 없으면 모델은 눈앞의 쿼리만 보고 국소적 최적화를 제안하지만, Harness가 "계획을 강제하는 힌트를 쓰지 않는다"는 제약을 걸어 두면 제안은 그 범위 안에 머무릅니다.
인덱스를 삭제하기 전에 최소한 무엇을 확인해야 하나요?
두 가지를 함께 확인하십시오. 하나는 sys.dm_db_index_usage_stats에 의한 사용률 통계, 다른 하나는 코드베이스와 저장 프로시저 정의에 대한 강제 참조 힌트 전수 검색입니다. 사용률 통계만으로는 최근 재시작 이후 기간만 반영됐을 가능성이 있습니다.
Sargability(사가빌리티)란 무엇인가요?
WHERE절 등의 검색 조건이 인덱스를 그대로 활용할 수 있는 형태인지를 나타내는 성질입니다. 열에 함수를 적용하거나 암시적 형변환이 발생하는 조건식은, 인덱스가 있어도 사용되지 않고 테이블 스캔이 되기 쉽습니다. 힌트로 무리하게 사용시키는 대신 조건식 작성 방식을 재검토해 확보합니다.
MAXDOP처럼 병렬도를 제어하는 힌트도 같은 이유로 금지되나요?
아닙니다. 이 문서가 다루는 것은 FORCE INDEX나 조인 힌트, FORCESEEK/FORCESCAN처럼 실행계획의 인덱스 선택·조인 순서를 AI가 고정해 버리는 종류의 힌트입니다. MAXDOP과 같은 병렬도·리소스 제어용 힌트는 성격이 다른 설정이며, 관련 문서(MAXDOP와 Cost Threshold for Parallelism 설정)에서 다룹니다.
この文書がカバーする質問
- 왜 AI마다 SQL 튜닝 제안 내용이 다른가
- 쿼리 힌트를 쓰면 어떤 리스크가 있는가
- 인덱스를 삭제하기 전에 무엇을 확인해야 하는가
リスク表示の意味
- 参照のみデータと設定を変更しません。
- 低影響は限定的ですが、権限と負荷の確認が必要です。
- 中性能・ロック・コストに影響する可能性があります。
- 高障害・データ損失・復旧作業が発生する可能性があります。
- 専門家レビュー必須本番適用前に別途レビューが必須です。
GIIPの対応範囲
Giip AI Harness는 생성·제안하는 SQL에 FORCE INDEX나 명시적인 조인 순서 힌트를 포함시키지 않는 것을 설계상의 제약으로 두고 있으며, 성능 개선 제안은 인덱스 설계 재검토, 통계 정보 정비, 쿼리의 Sargability 확보 등 CBO의 판단을 저해하지 않는 수단으로 한정합니다. 또한 인덱스 수명 주기 변경(신설·통합·삭제)을 검토할 때는, 특정 시점의 사용률 통계뿐 아니라 해당 인덱스를 강제로 참조하는 코드가 남아 있지 않은지 전수 검색을 함께 수행하는 것을 운영상의 전제로 삼고 있습니다.
執筆・技術検証
GIIP プロダクション運用チーム
大規模Webサービス、SQL Server、Oracle、AWS、Azureの設計・移行・運用に約30年従事。x12largeクラスのAWS RDS for SQL Server環境12セット、約12万テーブルのOracle環境、約3TBのTiDBからAurora MySQLへの移行を経験。現在も複数のクラウドデータベースと約30のWebサービスを、AIエージェントと人間の専門家が継続的に監視・運用しています。
関連サービス
쿼리 힌트 의존도를 점검하고 CBO 친화적 구조로 재설계하기
同じ確認を複数の環境で継続する必要がある場合は、運用体制ごと相談できます。
쿼리 힌트 의존도를 점검하고 CBO 친화적 구조로 재설계하기