MyBatis에서 #과 $의 차이에 대해서 포스팅을 하려고 한다.
XML파일에 작성된 쿼리가 DB에서 수행될 때 Bind 변수(#)와 Literal 변수($)에 따라 DB 조회 시 성능차이를 야기할 수 있다.
먼저 Literal 변수로 작성한 쿼리이다.
위와 같은 경우 만약 USER_ID가 111일 경우 WHERE USER_ID = '111'으로 바뀌고 USER_ID가 222일 경우 WHERE USER_ID = '222'로 파싱된다. 이를 하드 파싱이라고 하며 DB는 바뀌는 파라메터에 따라 Shared Pool/Library Cache에서 다른 쿼리로 인식하여 매번 Hard Parsing이 이루어진다. 매번 실행계획이 바뀔 수 있다.
반면 Bind 변수로 작성한 쿼리이다.
바인드 변수로 작성된 쿼리의 경우 WHERE USER_ID = :B 형태로 인식하여 최초 1회 Hard Parsing이 이루어지고 그 다음부터는 캐시에서 가져오기 때문에 빈번한 Hard Parsing으로 인한 성능상 단점을 보완할 수 있다. 매번 실행계획이 같다.
이 외에도 Bind 변수를 활용한 쿼리는 SQL Injection을 예방할 수 있다.
하지만 Bind 변수로 작성된 쿼리가 좋은가.
Bind 변수로 작성된 쿼리는 매번 동일한 실행계획을 갖게 된다.
가령 다음과 같은 상황이 있을 수 있다.
위에서 제시한 예제 테이블(TBL)에서 USER_ID가 PK가 아니다.
USER_ID='111', '333' 등 USER_ID가 홀수인 경우 각각 row수가 10건씩 존재한다.
반면 USER_ID='222', '444' 등 USER_ID가 짝수의 경우 row수가 1000건 혹은 그 이상이라고 가정하자.
이때 USER_ID가 홀수인 경우는 index scan이 유리하고 짝수인 경우 full scan이 유리할 것이다.
리터럴 변수($)로 쿼리를 수행한 경우 쿼리 수행시 매번 다른 쿼리로 인식하여 DB 옵티마이저에 의해 홀수일 때는 Index scan을 하고 짝수일 때는 Full scan을 할 것이다.
반면 바인드 변수일때는 일정한 실행계획에 의해 홀수/짝수일 때 조회 속도가 크게 차이가 날 것이다.
즉 무조건 바인드 변수가 옳은 것은 아니라고 할 수 있다.
그럼에도 불구하고 하드파싱을 막는 것과 일정한 실행계획을 갖는 다는 것이 큰 이점인 것같다. 만약 가까운 미래(?)에 DB가 발전함에 따라 파싱이든 실행계획이든 알아서 판단해주는 미래가 온다면 리터럴이든 바인드든 상관없이 쓰게 되는 날이 올 수도 있지않을까
피드 구독하기:
댓글 (Atom)
2022년 회고
올해는 블로그 포스팅을 열심히 못했다. 개인적으로 지금까지 경험했던 내용들을 리마인드하자는 마인드로 한해를 보낸 것 같다. 대부분의 시간을 MLOps pipeline 구축하고 대부분을 최적화 하는데 시간을 많이 할애했다. 결국에는 MLops도 데이...
-
MSSQL에는 저장프로시저가 아주 강력하고 문법 자체도 편하기(?) 때문에 토이프로젝트를 진행할 때 DB를 MSSQL을 주로 사용한다. 본인 노트북, 혹은 데스크탑에 MSSQL을 설치하고 SSMS로 접속을 하려고 할 때 서버이름에 loc...
-
MyBatis에서 #과 $의 차이에 대해서 포스팅을 하려고 한다. XML파일에 작성된 쿼리가 DB에서 수행될 때 Bind 변수(#)와 Literal 변수($)에 따라 DB 조회 시 성능차이를 야기할 수 있다. 먼저 Literal 변수로 작성한...
-
웹사이트에 대한민국 지도(시도, 시군구, 법정동)를 표현하고 각각 권역에 데이터를 입혀야하는 사람들에게 도움이 되기를 바라며 포스팅한다. 필자도 필요해서 집에서 며칠동안 연구해본 결과 전처리 과정이 꽤나 난감했다. 사실 데이터를 엮어서 표현하기 위...
댓글 없음:
댓글 쓰기