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...
-
화면에서 프린트 기능을 구현했는데 글자들은 잘 나오지만 CSS가 안먹는 경우가 간혹 발생했다. 마크업된 CSS를 불러오지 못해 발생하는 문제로 판단했고 약간의 트릭으로 해결할 수 있었다. 아래는 구현된 화면이다. 이 화면을 출력하고자 다...
-
요즘같이 디스크 용량 걱정이 없는 세상에서는 MSSQL Shrink를 볼 일이 없을 것 같았는데 얼마 전 회사에서 SHRINK를 할 일이 생겨서 진행했었다. 디스크 용량이 약 4테라이고 해당 디스크는 db file만 존재하여 딱히 지울 파일이 없었...
댓글 없음:
댓글 쓰기