본문 바로가기
데이터베이스/MySQL

[SQL] bind variable의 사용 의미

by devebucks 2019. 6. 11.
728x90

바인드 변수 정의

  • 바인드 변수는 PL/SQL 또는 SQL 쿼리문에서 WHERE 절에 value 값을 (?)로 사용하는 변수이다.
  • 호스트 환경에서 생성되어 데이터를 저장한다.
  • print 명령어를 사용해서 변수를 확인할 수 있다.

바인드 변수를 사용하는 이유


1) 성능 향상을 위한 사용 목적

바인드 변수가 뭔지 알아보는 과정에서 지금까지 몰랐던 MySQL이 쿼리를 받고부터 어떤 절차를 가지고 쿼리가 실행되었는지 알지 못하고 사용해 왔다는 것을 알았다. 관련 블로그를 정독하고 정리하였다.

쿼리를 받으면 MySQL에서 처리 절차

1. 구문 오류 체크 (parse)
2. 공유 역역에서 해당 구문 검색 (parse)
3. 권한 체크 (parse)
4. 실행 계획 수립 (parse)
5. 실행 계획 공유영역에 저장 (parse)
6. 쿼리 실행 (Excute)

2번 단계인 공유 영역에서 해당 구문이 동일한 구문을 찾게 되면, 6번 쿼리 실행으로 건너뛴다고 한다.
1번~6번 까지 모두 실행되면 이를 Hard Parsing 이라 하고, 2번에서 6번으로 바로 넘어가면  Soft Parsing 이라고 한다. 당연 절차적으로  Soft Parsing 이  Hard Parsing 보다 성능적으로 우세하다.

* parse는 SQL 실행 과정 중 일부이다.
공부하면서, 쿼리문을 작성하는 방식에 따라서 CPU자원이 사용되는 양이 다르다는 것을 알았다.
가령, 자바에서 쿼리를 작성할 경우.
나는 당연히 아래와 같은 방식으로 쿼리문을 완성하고, mysql에 날렸다.

String variable ="example_value";
String query = "SELECT * FROM example_table WHERE variable = " + variable;

당연히 동적으로 변하는 입력값에 대응하기 위한 쿼리문 작성을 의도하여 위와 같은 코드를 만들었지만, 저 방법은 입력값인 'variable'값이 변하면 쿼리도 바뀌게 되어서 기존에 공유 영역에 저장되어 있을 다음과 같은 1. 쿼리가 있다면,

1.

String query = "SELECT * FROM example_table WHERE variable = example_value;

2.

String query = "SELECT * FROM example_table WHERE variable = differ_value;

2. 쿼리가 들어오면 공유영역의 1. 쿼리를 재사용하지 못하고, 쿼리 실행 절차인 1~6번 과정을 새로 수행해야 하는  Hard Parsing 이 일어나게 된다. 즉, 위의 작성된 쿼리는 공유 영역에 저장된 쿼리와 Cursor Sharing이 이루어지지 않는다.

반면, 이제 바인드 변수가 사용되는 이유가 여기 나온다.

String query = "SELECT * FROM example_table WHERE variable = ?";

쿼리 자체에 변수를 사용하고 있어서 공유 영역에 저장되어 있는 쿼리와 무조건 동일해질 수 있다. Cursor Sharing이 되어서  Soft Parsing 이 가능해 진 것이다!!!

반복 수행문 안에서 사용되는 쿼리의 경우 바인드 변수를 사용하지 않게 되면 쿼리 수행 횟수만큼의 매번 parsing을 하기 때문에  Hard Parsing 에 대한 부하가 발생한다고 한다. 이 경우 바인드 변수 사용이 성능을 고려해서 권장된다고 한다.

재파싱이 일어나는 것이 CPU를 많이 사용하게 된다. 바인드 변수를 사용하는 경우에는 SQL문이 메모리에 저장될 가능성이 매우 높아 SQL문을 필요로 하는 다음 작업에서 SQL 쿼리 구문 최적화 분석 작업을 건너뛰고 빠르게 SQL 쿼리 구동이 가능해진다.

2) 동일한 쿼리에 WHERE 절의 변숫값의 동적 반영.

MySQL에서 질의문을 날릴 때, where절에 매번 변경되는 변수의 값을 동적으로 반영하기 위해서 사용한다.

'?' Bind Variable은 어디서 가져올까?

Bind Variable을 공부하는데 발생한 궁금증.
1) 사용하는 데 앞서 Bind Variable은 어떻게 사용하는지?
2) '?'는 어디서 값이 채워질까?
3) JAVA에서 적용하려면?

다음 3가지의 궁금증은 아래의 예시 코드로 단번에 해결할 수 있었다.
나는 사실 JAVA에서 Bind Variable을 적용한 경험이 있었다. Bind Variable을 사용한 쿼리를  PreparedStatement 라고 한다. 하지만, 이게 Bind Variable인지 알지 못하고 사용하였다. 구글링 개발자의 폐해이다.

String query ="SELECT * FROM example_table WHERE id= ?";
PreparedStatement ps = con.prepareStatement(query);
ps.setint(1, id);

위와 같은 방식으로 코딩하면, Bind Variable의 기능을 사용할 수 있게 된다. 매번 다른 쿼리가 DBMS에 입력되어 매번 parsing이 일어나는 부하를 주지 않게 된다.

공부 과정 도움을 받은 글..

https://blog.naver.com/jevida/220426939740

http://egloos.zum.com/messfilm/v/2166470

728x90

댓글