AWS Services/Athena

[Athena] [쿼리튜닝] LIKE 절 vs RegEX 패턴 쿼리 속도비교 실험

[앙금빵] 2024. 4. 7.

개요

본 글에서는 대용량 데이터 세트에서 동작하는 쿼리에서 LIKE 절을 최소화 하였을때 쿼리 성능이 개선이 되어지는지에 대한 확인 실험을 진행하는 것을 목표로 한다.

 

이는 AWS Athena 쿼리 성능 향상 팁 문서에서도 안내하는 내용이며 일반적으로 쿼리 튜닝시 알려져 있는 지식이다. 아래 예시에서는 RegEX 구문을 이용하여 절약여부를 테스트한 내용이다.

LIKE 최적화 예시

 

 

LIKE 절을 사용하면, 데이터베이스는 지정된 패턴을 데이터 세트의 각 행의 데이터와 비교해야 한다. 이 과정은 각 행을 순차적으로 검색하면서 엔진이 문자 단위로 일치 여부를 확인해야 하므로, 특히 큰 데이터 세트에서 높은 수의 비교가 필요하여 자원 집약적일 수 있다.

 

그러나 반드시 LIKE 절 대신 RegEX 로 대체한다고 해서 반드시 성능이 좋아지는 것은 아니다. 이는 결과를 얻고자 하는 쿼리 특성에 따라 다르며 StackOverflow 답변 내용에서는 단일 조건에서는 LIKE 조건이 더 성능이 좋고, 다중 조건에서는 RegEX 패턴을 이용하는 것이 더 성능이 좋다고 한다.

 

현재 겪는 불편점


첫째, 패턴은 단순하지만 많은 조건에 대하여 동일한 패턴을 적용해야 한다. 이 때문에 단순한 로직이지만 불필요하게 쿼리의 길이가 길어지게 되며 가독성이 떨어지게 된다.

 

둘째, 신규 기능 혹은 서비스가 추가되어지는 경우 현재 적용된 쿼리에 일일이 쿼리 수정을 해주어야 하며 이는 비효율적이다.

 

아래 예시와 같이 많은 조건에 대하여 동일한 패턴이고 같은 패턴에서 appGroup d,e,f가 신규로 추가되어지는 경우 모든 패턴마다 같은 내용을 추가해야 한다는 반복작업이 발생되어지게 된다.

 

<기존 쿼리>

/* test1 - appGroup */
WHEN request_url LIKE 'https://example.com:443/test/%appGroup=a%'        THEN 'test_a'
WHEN request_url LIKE 'https://example.com:443/test/%appGroup=b%'        THEN 'test_b'
WHEN request_url LIKE 'https://example.com:443/test/%appGroup=c%'        THEN 'test_c'
WHEN request_url LIKE 'https://example.com:443/test/%'                   THEN 'test_Other'


/* test2 - appGroup */
WHEN request_url LIKE 'https://example.com:443/test2/%appGroup=a%'        THEN 'test_a'
WHEN request_url LIKE 'https://example.com:443/test2/%appGroup=b%'        THEN 'test_b'
WHEN request_url LIKE 'https://example.com:443/test2/%appGroup=c%'        THEN 'test_c'
WHEN request_url LIKE 'https://example.com:443/test2/%'                   THEN 'test_Other'

 

<쿼리 appGroup d,e,f가 추가되어지는 경우>

/* test1 - appGroup */
WHEN request_url LIKE 'https://example.com:443/test/%appGroup=a%'        THEN 'test_a'
WHEN request_url LIKE 'https://example.com:443/test/%appGroup=b%'        THEN 'test_b'
WHEN request_url LIKE 'https://example.com:443/test/%appGroup=c%'        THEN 'test_c'
WHEN request_url LIKE 'https://example.com:443/test/%appGroup=d%'        THEN 'test_d'
WHEN request_url LIKE 'https://example.com:443/test/%appGroup=e%'        THEN 'test_e'
WHEN request_url LIKE 'https://example.com:443/test/%appGroup=f%'        THEN 'test_f'

WHEN request_url LIKE 'https://example.com:443/test/%'                   THEN 'test_Other'


/* test2 - appGroup */
WHEN request_url LIKE 'https://example.com:443/test2/%appGroup=a%'        THEN 'test_a'
WHEN request_url LIKE 'https://example.com:443/test2/%appGroup=b%'        THEN 'test_b'
WHEN request_url LIKE 'https://example.com:443/test2/%appGroup=c%'        THEN 'test_c'
WHEN request_url LIKE 'https://example.com:443/test2/%appGroup=d%'        THEN 'test_d'
WHEN request_url LIKE 'https://example.com:443/test2/%appGroup=e%'        THEN 'test_e'
WHEN request_url LIKE 'https://example.com:443/test2/%appGroup=f%'        THEN 'test_f'
WHEN request_url LIKE 'https://example.com:443/test2/%'                   THEN 'test_Other'

 

기대하는 개선점

 

1순위. 쿼리를 간결하게 만들어 가독성을 높인다.

2순위. 쿼리 성능

 

실험대상은 통계를 확인하는데 이용되어지는 쿼리이며 24/7하게 실행되어지는 쿼리는 아니다. 그렇기에 가독성을 높이고 기존 쿼리 대비 비슷한 퍼포먼스만 나오더라도 충분히 가치가 있다.


 

그렇다면, 실제 운영하는 데이터 내 쿼리에서 LIKE절 대신 RegEX 패턴을 이용하게 되어지는 경우 유의미한 성능향상을 체감할 수 있는지 알아보도록 하자.

 

실험

실험 표본

실험 대상으로는 6억, 14억개의 행에 대하여 패턴별 (1) LIKE 구문을 일일이 넣어준 쿼리 (2) Regex 패턴을 사용하여 LIKE 구문을 최소화한 쿼리 대상으로 쿼리 속도를 비교해보자.

 

1. LIKE 구문을 패턴별 적용한 쿼리패턴 예시 - 정규식 미적용

/* test1 - appGroup */
WHEN request_url LIKE 'https://example.com:443/test/%appGroup=a%'        THEN 'test_a'
WHEN request_url LIKE 'https://example.com:443/test/%appGroup=b%'        THEN 'test_b'
WHEN request_url LIKE 'https://example.com:443/test/%appGroup=c%'        THEN 'test_c'
WHEN request_url LIKE 'https://example.com:443/test/%appGroup=d%'        THEN 'test_d'
WHEN request_url LIKE 'https://example.com:443/test/%appGroup=e%'        THEN 'test_e'
WHEN request_url LIKE 'https://example.com:443/test/%appGroup=f%'        THEN 'test_f'

WHEN request_url LIKE 'https://example.com:443/test/%'                   THEN 'test_Other'

 

2. RegEX 패턴을 이용한 쿼리패턴 예시 - 정규식 적용

WHEN request_url LIKE 'https://example.com:443/test/%' 
AND request_url LIKE '%appGroup=%' THEN 'test_' || REGEXP_EXTRACT(request_url, 'appGroup=([^&]+)', 1)
WHEN request_url LIKE 'https://example.com:443/test/%' THEN 'test_Other'

 

실험결과

표본1. 6억개의 행 (10.62% 성능개선)

정규식 사용한 경우는 평균 2분 2초, 미사용한 경우 평균 2분 15초가 소요되어 졌으며 약 14초 차이를 가졌다.

 

표본2. 14억개의 행 (10.42% 성능개선)

정규식 사용한 경우는 평균 4분 20초, 미사용한 경우 평균 분 51초가 소요되어 졌으며 약 31초 차이를 가졌다.

 

결론

해당 실험을 통해 크게 2가지 이득을 보게 되었다.

 

첫째, 성능적으로의 이득

다중 조건에서 RegEX 패턴을 사용하였을 시 10% 이상의 성능 개선이 되어졌음을 확인하였다. 또한, 데이터 셋이 커지면 커질수록 개선의 효과는 더욱 커진다.

 

둘째, 유지보수 관점에서의 이득

정규 표현식(RegEX)을 사용하여 정의된 패턴은 쿼리의 길이를 단축시켰으며 이는, 기존 쿼리 대비 간결하게 만들어, 이해하기 쉽고 관리의 용이성을 확대시켰다.

댓글