개발 저장소/개발 지식 저장소

[Oracle] 리터럴 변수 대신 바인드 변수를 사용해서 DB 부하 감소시키기

이거비버 2023. 6. 28. 17:23
반응형

고객사에 배포되어 있는 Django 프로젝트는
JAVA가 사용하는 프로젝트에 추가되는 방식이라서

기존 JAVA가 사용하는 DB를 헤치지 않으면서, 고객사 정책에 맞는 DB만 생성을 해야 한다.

그래서 Django가 제공하고 있는 ORM 방식을 사용하지 않고 로우쿼리로 개발했다.

로우쿼리로 개발하는 것은 처음이라 검색해 가며 어찌어찌 완성을 하긴 했는데
고객사 DBA분이 쿼리문을 보시더니 이렇게 말했다.

 

하... 이 쿼리문 누가 짰어요?


DBA분이 몇몇 쿼리문을 바꿔주시긴 했는데 형태가 더 복잡해서 왜 이렇게 하지? 싶었다.

일단, 동작하는데 이상은 없어 넘어간다고 해서 알겠다고 했다.

(사실상 프로젝트 마감 단계라 내가 욕심을 부려 이래저래 공부하면서 수정을 하기엔 벅찬 상황)

 

그런데 오늘 고객사의 갑 회사인 End-user쪽 DBA로부터 쿼리문의 리터럴 변수를 모두 바인드 변수로 바꿔달라고 요청이 들어왔다.

오후 4시에 연락 와서 원격 접속해서 당일 내로 고쳐달라는 연락이었다.

엥 나는 6시에 퇴근하고 와이프한테 삼겹살을 구워줘야 하는데..?

 

그나저나..

리터럴 변수는 뭐고 바인드 변수는 뭐지..?

 

검색을 해보니 예전에 고객사 DBA분이 쿼리문을 수정해 줬던 스타일이었다.

일단 시간이 없으니 후따닥 바인드 변수로 죄다 바꾸고 동작 테스트 하고..

원격 접속해서 재배포를 해줬다.

 

그리고 찾아봤다.

 

바인드 변수는 왜 쓰는 건가?

 

찾아보니 리터럴 변수는 상수값으로 직접 선언된 경우 변수 재사용이 되지 않고 다시 Parsing을 거치게 되어 Database에 부하를 주게 된단다.

 

<리터럴 변수 예시>

SELECT * FROM TABLE01 WHERE COL01 = {data}

 

바인드 변수는 parameter를 사용하는 방식이다.

뭐.. 큰 차이는 없고 각 변수의 닉네임을 정해주고, 뒤에서 닉네임에 실제 변수를 붙여주는 방식이랄까?

 

<바인드 변수 예시>

SELECT * FROM TABLE01 WHERE COL01 :col01, {col01=data}

 

큰 차이도 없어 보이는데 왜 바인드 변수로 바꿔달라는 걸까?

그래서 찾아봤다.

 

바인드 변수를 쓰는 이유는 아래와 같다.

 

  1. 보안성: 바인드 변수를 사용하면 SQL 주입 공격과 같은 보안 취약점을 방지할 수 있습니다. 사용자 입력이 SQL 문에 직접 포함되지 않고 바인드 변수로 전달되기 때문에 악의적인 사용자가 악의적인 SQL 코드를 주입할 수 없습니다.
  2. 성능: 바인드 변수를 사용하면 SQL 문이 미리 컴파일되고 캐시에 저장되므로 재사용되는 경우 성능이 향상될 수 있습니다. 매번 쿼리를 실행할 때마다 SQL 문이 다시 컴파일되는 것을 피할 수 있습니다.
  3. 가독성과 유지 보수성: 바인드 변수를 사용하면 SQL 문이 더 가독성이 좋아집니다. SQL 문과 변수가 분리되어 있으므로 코드를 이해하기 쉽고 유지 보수하기도 쉽습니다. 변수의 값만 변경하면 되므로 SQL 문 자체를 수정할 필요가 없습니다.
  4. 데이터 형식 일치: 바인드 변수를 사용하면 데이터 형식 일치 문제를 방지할 수 있습니다. 데이터베이스 드라이버가 변수의 데이터 형식을 자동으로 처리하므로 사용자가 수동으로 형식 변환을 수행할 필요가 없습니다.

이러한 이점들로 인해 바인드 변수를 사용하는 것이 권장된다고 한다.

앞으로 바인드 형식의 쿼리문을 사용해야겠다.

반응형