Babelfish에서 ANTLR 구문 분석 캐시 사용
Babelfish 버전 5.7.0 및 6.2.0부터는 T-SQL 저장 루틴(프로시저 및 함수)에 지속성 ANTLR 구문 분석 결과 캐시를 사용하여 첫 번째 실행 시 발생하는 지연 시간을 줄일 수 있습니다.
프로시저 구문 분석 캐시 사용 시 알아둘 사항:
-
대규모 T-SQL 루틴(수백 내지 수천 라인)의 경우 새로운 세션에서 처음 실행될 때마다 전체 T-SQL 구문 분석을 다시 수행해야 하는 오버헤드가 더 이상 발생하지 않습니다.
-
구문 분석 결과는 프로시저나 함수를
CREATE또는ALTER하는 시점에 한 번 직렬화되어 카탈로그에 저장되며, 여러 세션 간에 재사용됩니다. 이는 SQL Server의 시스템 전체 캐싱 동작을 에뮬레이트한 것입니다. -
이 기능은 세션 수준의 GUC 변수인
babelfishpg_tsql.enable_antlr_parse_cache로 제어하며,sys.enable_antlr_parse_cache()를 통해 루틴별로 개별 재정의할 수도 있습니다. -
이 기능은 기본적으로 OFF 상태입니다.
성능: 대규모 루틴의 경우 ANTLR 구문 분석에 최대 수초가 걸릴 수 있습니다. ANTLR 구문 분석 캐시를 사용하면 첫 번째 실행 시의 구문 분석 시간이 몇 밀리초 수준으로 줄어듭니다. 동일한 세션 내 후속 실행은 세션 내 캐시에서 처리되므로 1밀리초 미만이 소요되며 이 기능 설정 여부의 영향을 받지 않습니다.
ANTLR 구문 분석 캐시 이해
Babelfish는 세션에서 루틴이 처음 실행될 때 루틴의 본문을 구문 분석하여 T-SQL 구문을 검증해야 합니다. 일반적으로 이 구문 분석 결과는 해당 세션의 수명 동안에만 캐싱되므로, 새로운 연결이 생성될 때마다 매번 처음부터 다시 구문 분석이 수행됩니다. 구문 분석 캐시는 이 구문 분석 결과를 카탈로그에 저장하여 지속적으로 유지하므로 새로운 세션에서도 이를 재사용할 수 있습니다.
작동 방식:
-
CREATE/ALTER: 캐싱 기능이 활성화되어 있으면, Babelfish는 루틴을 구문 분석한 후 직렬화된 구문 분석 결과를 지속성 캐시에 저장합니다. -
지속성 캐시 항목이 없는 상태에서 첫 실행 시: 캐싱된 항목이 존재하지 않는 경우(예: 캐싱 기능이 활성화되기 전에 루틴이 생성된 경우), Babelfish는 일반적인 ANTLR 구문 분석을 수행하고 지속성 캐시에 해당 내용을 채웁니다.
-
이후 다른 세션에서 첫 실행 시: Babelfish는 구문 분석을 다시 수행하는 대신 캐싱된 구문 분석 결과를 로드하고 역직렬화합니다. 이 단계에서 실제로 실행 시간이 단축됩니다.
-
동일한 세션에서의 후속 실행 시: 세션 내 캐시에서 결과가 제공됩니다(이전과 동일하게 동작).
-
캐싱된 결과가 누락되었거나 다른 버전의 Babelfish에서 생성된 경우 Babelfish는 일반적인 ANTLR 구문 분석을 수행하며 캐싱이 활성화되어 있을 때 지속성 캐시를 다시 채웁니다.
-
Babelfish가 캐싱된 결과를 직렬화하거나 역직렬화하는 과정에서 오류가 발생하면 해당 문은 실패하고 오류를 반환합니다. 이 경우 문제가 발생한 루틴의 캐싱을 비활성화하고 명령문을 재시도하거나, 캐시 GUC 변수를 비활성화한 후 새 세션에서 다시 시도하세요. 오류가 지속될 경우 AWS 지원에 문의하세요.
구문 분석 시간 단축 효과 확인
각 배치의 Babelfish T-SQL Batch Parsing Time을 기록하는 SET BABELFISH_STATISTICS PROFILE ON을 사용하여 이 기능의 효과를 측정할 수 있습니다. 먼저, 캐싱을 활성화하여 지속성 캐시를 채우는 대규모 프로시저를 생성합니다. 그 다음, 서로 다른 두 개의 새로운 세션에서 이 프로시저의 첫 번째 실행을 비교합니다. 하나는 캐싱을 비활성화하여 지속성 캐시 항목을 무시하는 세션이고, 다른 하나는 캐싱을 활성화하여 이를 재사용하는 세션입니다. 또는 프로시저가 생성될 당시 캐싱이 활성화되어 있지 않았다면, 캐싱을 활성화한 상태에서 두 개의 독립된 새 세션을 열어 실행해 봅니다. 이 경우 첫 번째 실행 시 지속성 캐시가 채워지며, 두 번째 세션 실행 시 이를 재사용하게 됩니다.
다음 예시에서는 먼저 지속성 캐시를 채우기 위해 캐싱 기능을 ON으로 설정한 상태에서 프로시저를 생성합니다.
-- New session 0: caching ON (at CREATE PROCEDURE time) SELECT set_config('babelfishpg_tsql.enable_antlr_parse_cache', 'on', false); GO CREATE PROCEDURE dbo.updateInformation @region VARCHAR(50) AS BEGIN ... END; GO
다음으로, 캐싱이 OFF(기본값) 상태인 새로운 세션에서 해당 프로시저를 실행합니다.
-- New session 1: caching OFF (default) SET BABELFISH_STATISTICS PROFILE ON; GO EXEC dbo.updateInformation @region = 'EMEA'; -- first call in this session GO
통계 프로파일을 확인해 보면 구문 분석 시간이 길게 나타납니다.
Babelfish T-SQL Batch Parsing Time: 20359.465 ms
마지막으로, 캐싱이 활성화된 또 다른 새로운 세션에서 해당 프로시저를 실행합니다.
-- New session 2: caching ON SELECT set_config('babelfishpg_tsql.enable_antlr_parse_cache', 'on', false); GO SET BABELFISH_STATISTICS PROFILE ON; GO EXEC dbo.updateInformation @region = 'EMEA'; -- first call in this session GO
통계 프로파일을 확인해 보면 구문 분석 시간이 현저히 짧아졌습니다.
Babelfish T-SQL Batch Parsing Time: 150.927 ms
새로운 세션에서의 첫 번째 실행 시, 캐싱된 구문 분석 트리를 재사용하게 되면 구문 분석 시간이 약 20초에서 약 0.15초로 단축됩니다. 동일한 세션 내 두 번째 이후의 실행은 두 경우 모두 세션 내 캐시에서 처리되므로 1밀리초 미만이 소요되며 GUC 설정의 영향을 받지 않습니다.
세션 단위 캐시 활성화
이 기능은 세션 수준의 GUC(기본값 OFF)를 통해 제어됩니다.
-- Enable parse caching for the current session SELECT set_config('babelfishpg_tsql.enable_antlr_parse_cache', 'on', false); GO -- Disable for the current session SELECT set_config('babelfishpg_tsql.enable_antlr_parse_cache', 'off', false); GO
참고
-
이 GUC는 세션 범위 내에서 적용되며, 세션이 종료되면 기본값(OFF)으로 초기화됩니다.
-
현재 이 GUC는
sp_babelfish_configure를 통해 클러스터 전체 수준에서 구성할 수 없습니다.
루틴별 캐시 제어
sys.enable_antlr_parse_cache를 사용하여 개별 루틴에 대한 세션 GUC 설정을 재정의할 수 있으며, 이 함수는 해당 루틴의 객체 ID를 인수로 받습니다.
-- Force caching ON for a specific routine (even if the session GUC is OFF) SELECT sys.enable_antlr_parse_cache(sys.object_id('dbo.my_proc'), true); GO -- Force caching OFF for a specific routine — "kill switch" -- (clears any cached data and blocks caching even if the session GUC is ON) SELECT sys.enable_antlr_parse_cache(sys.object_id('dbo.my_proc'), false); GO -- Reset to default; the routine follows the session GUC SELECT sys.enable_antlr_parse_cache(sys.object_id('dbo.my_proc'), NULL); GO
참고
-
캐시 설정을 변경하려면 루틴의 소유자이거나 sysadmin 역할의 멤버여야 합니다.
-
루틴별 설정은 여러 세션 간에 지속적으로 유지되며(카탈로그에 저장됨),
ALTER를 수행하더라도 그대로 보존됩니다. 해당 루틴이 삭제되면 이 설정도 함께 제거됩니다.
캐시 통계 확인
sys.antlr_parse_cache_stats()는 현재 세션의 구문 분석 캐시 활동 정보를 반환합니다.
SELECT * FROM sys.antlr_parse_cache_stats(); GO
다음 표는 출력 결과의 각 열에 대한 설명입니다.
| 열 | 설명 |
|---|---|
cache_hits |
캐시된 구문 분석 결과가 재사용된 루틴 실행 횟수입니다. |
cache_misses |
캐싱이 활성화되어 있었으나 사용할 수 있는 캐시 항목을 찾지 못한 루틴 실행 횟수입니다. |
cache_writes |
지속성 캐시 기록에 성공한 횟수입니다. |
cache_evictions |
무효화되거나 제거된(예: 종료 스위치 작동 또는 GUC 설정 변경) 캐시 항목 수입니다. |
cache_errors |
직렬화 또는 역직렬화 실패 횟수입니다. |
카운터는 세션별로 집계되며, 새로운 연결이 생성되면 초기화됩니다.
예제 시나리오
-- Enable caching for this session SELECT set_config('babelfishpg_tsql.enable_antlr_parse_cache', 'on', false); GO CREATE PROCEDURE dbo.report_proc @region VARCHAR(50) AS BEGIN -- large multi-statement T-SQL body ... SELECT @region; END; GO -- First execution in a brand-new session: served from the persistent cache (fast) EXEC dbo.report_proc @region = 'APAC'; GO -- Inspect cache activity for this session SELECT * FROM sys.antlr_parse_cache_stats(); GO -- Opt this routine out of caching regardless of the session setting SELECT sys.enable_antlr_parse_cache(sys.object_id('dbo.report_proc'), false); GO
업그레이드 고려 사항
-
ANTLR 구문 분석 캐시는 특정 Babelfish 버전에 바인딩됩니다. Babelfish 버전이 변경되면 캐싱된 구문 분석 결과는 더 이상 재사용되지 않습니다. 캐싱이 활성화된 상태에서 루틴을 새로 실행하면 구문 분석이 다시 수행되며, 캐시도 자동으로 다시 채워집니다.
-
버전 5.7.0 및 6.2.0 이전에 생성된 기존 루틴은 캐싱이 활성화된 상태에서 다음번에
CREATE/ALTER를 수행하거나, 콜드 세션에서 처음 실행될 때 캐시에 저장됩니다.
중요 제한 사항
-
기본적으로 비활성화됨: 이 기능은 세션별로 명시적으로 활성화(또는 루틴별로 강제 설정)해야 합니다.
-
연결 유형: 이 캐시는 TDS(SQL Server 프로토콜) 연결에서만 활성화되며, psql/libpq 연결 시에는 활성화되지 않습니다.
-
캐싱 제외 대상: 현재 릴리스에서는 트리거, 이벤트 트리거, 인라인 테이블 값 함수(ITVF)는 캐싱되지 않습니다.
-
클러스터 전체 구성: 현재
sp_babelfish_configure를 통해 세션 GUC를 설정할 수 없습니다.