똘이의 개발 Life

[ Oracle ] 바인드 변수 본문

DB

[ Oracle ] 바인드 변수

또리또리똘 2024. 4. 2. 09:20
728x90

이번에 이직한 회사에서는 코드 리뷰가 굉장히 자연스러운 문화로 자리 잡혀있다.

코드 리뷰를 받으면서 몇 가지 알게된 정보를 나누려고 한다. 

 

바인드 변수

Oracle DB 는 SQL 문을 실행하면 해당 문장에 대한 구문 검사와 문법적 오류 검사를 거쳐 가능한 여러 가지 실행 계획을 세운다. 

그 후 가장 효율적인 실행 계획을 선택하는 등 복잡한 과정을 거쳐 SQL 문을 실행하고 처리하는데 이러한 과정이 상당히 무거운 작업이다. 

Oracle DB 는 동일한 SQL 문장이 여러 번 실행되면 이전에 실행한 적이 있었던 SQL 문장인지 여부를 메모리에서 찾아보는데 , 만약에 찾으면 구문 검사와 오류 검사 등의 무거운 과정을 생략하고 이전에 실행했던 정보를 활용해 처리한다. 따라서 이때는 처리속도를 향상 시킬 수 있다. 

 

def example( temp : list[tuple( str , int )] ) :

sql = f""" select name , age , address 
			from example_table 
            where ( name , age ) in ( {','.join( f"('{temp[0]}',temp[1])" for element in temp )} )
        """
        
 ...

query = session.excute( text(sql) )

 

이렇게 위에 예시 코드가 있다. ( Python + Oracle )

문법적으로 틀렸을 수 있다. Python 을 현업에서 사용한지 1달도 되지 않았다... 

중요한건 문법이 아니라 형식이다. 본질에 집중 하면 좋을 것 같다. 저 위의 SQL 에서 name 과 age 에 들어가는 값들은 무조건 상수로 들어갈 것이다. 소위 내가 SQL 을 찍어서 excute 하는 것이다. 즉, 저 SQL 은 매번 무거운 과정( 문법 오류 확인 , 구문 검사 ) 를 거쳐야할 것이다. 하지만 아래처럼 코드를 짠다면? 

 

def example( temp : list[tuple( str , int )] ) :


    params : dict[ str , str | int ] = {} 
    sql = ( " select name , age , address "
            " from example_table "
            " where ( name , age ) in ( "
    )
    for cnt , element in enumerate( temp , 1 ) :
    	sql = f"{sql}(:name{cnt} , :age{cnt} ) "
        if cnt == len(temp) :
        	sql = f"{sql})"
        else :
        	sql = f"{sql},"
        
        params.update(
        	{
            	f"name{cnt}" : element[0] , #name
                f"age{cnt}" : element[1] , #age 
            }
        )
	# 쿼리 완성 
    
    session.excute( text(sql) , params )
    
    ...

 

위의 코드에서 SQL 만 따로 빼서 보면 

 

select name , age , address 
from _example_table
where ( name , age ) in ( ( :name1 , :age1 ) , ( :name2 , :age2 ), (:name3 , :age3)

 

이런식으로 만들어질 것이다. 

그리고 나서 저 :name1 부분에 params dict 에 넣어준 Key 값에 매치되는 value 값이 들어가면서 SQL 이 돌아갈 것으로 예측할 수 있다. 

 

WHERE 절의 비교 값을 상수로 처리하면 상수 값이 달라질 때마다 무거운 처리를 진행하지만 비교 값을 변수 처리를 하면 동일한 SQL 로 인식해 무거운 처리를 하지 않기 때문에 SQL 문의 처리 성능이 좋아진다.

 

이렇게 SQL 구문상에서 조건절에 들어가는 값으로 변수를 사용하는 것을 바인드 변수를 사용한다고 말한다.

 

DBA나 전문 튜너들이 튜닝을 하기 앞서 가장 먼저 확인하는 사항 중 하나가 바로 SQL 에서 바인드 변수를 사용했는지에 대한 여부일 정도로 이 변수는 성능에 있어 매우 중요한 요소이다. 

 

https://thebook.io/006696/0358/

 

오라클 SQL과 PL/SQL을 다루는 기술: ② 바인드 변수 처리 1

더북(TheBook): (주)도서출판 길벗에서 제공하는 IT 도서 열람 서비스입니다.

thebook.io

 

더 자세한 글은 위에 사이트를 참고하길 바란다. 위의 사이트의 내용을 생략하고 Python 에 맞는 코드를 조금 추가했다. 원문은 위에 글이니 이해가 가지 않을 경우 참고하길 바란다. 

 

 

728x90