일전에 C# Winform 프로그램(이하 클라이언트) 보안에 대해 궁금한 점을 올린적이 있었는데요,
결국 디컴파일은 피할수 없기때문에 핵심로직이나 DB에 접근해야하는 경우는 따로 API서버를 두고 사용하는 것이 좋을 것 같다는 생각을 했습니다.
그래서 일단 우분투서버에 도커를 설치 후 컨테이너에 API서버를 구축해서 해당 API서버에서 DB에 접근하도록 했는데요, 클라이언트에서 DB 조회나 삽입, 업데이트 등의 동작을 하기 위해 각각의 api 요청을 하게끔 했습니다.
api요청 → 서버에서 db 연결-> 필요한 작업 진행(조회, 삽입, 업데이트) → db 연결 해제 → 작업결과 리턴
이런 순서로 진행을 하는데, 여기서 궁금한점은 다수의 클라이언트 프로그램에서 api 동시요청이 많아지면
제 생각으로는 db연결과 해제를 계속해서 많이 반복하게 될 텐데 이 때 발생할만한 문제가 있을지, 그리고 저 반복으로 인해 응답시간에 영향이 생기지는 않을 지, 혹은 그 외 다른 이슈는 없을 지 궁금합니다!
성능 적인 부분은 저장 프로시저나 일반 쿼리 실행이나 큰 차이는 없습니다.
기본적으로 동일한 쿼리와 동일한 인덱스를 타는 조건이라면 캐싱 처리 되어
쿼리 구문을 다시 분석하지 않기 때문에 저장 프로시저 호출과 비슷하게 성능 제약은 없습니다.
저장 프로시저는 형상 관리가 어렵습니다.
저장 프로시저를 별도의 파일로 형상 관리 하지 않는 이상
내용 변경 이력 관리가 어려워 이러한 모습을 볼 수 있을 가능성이 있습니다.
[저장 프로시저]
xxx_select_01
xxx_select_01_02
xxx_select_01_02_최종
물론 회바회로 어떻게 관리하느냐에 따라 다를 수 있습니다.
ORM을 사용한다면 더욱이 저장 프로시저를 사용 할 이유는 없습니다.
저장 프로시저를 사용하게 되면 비지니스 로직이 저장 프로시저안에 포함될 가능성이 매우 높습니다.
이렇게 되면 특정 문제가 발생 되었을때 DB의 저장 프로시저 부분이 문제인지 프로그램 코드의 오류인지 확인이 어렵고 제3자가 볼때는 더더욱 두개의 관리 부분을 다 확인해야 하는 문제가 있습니다.
간혹 ‘저장 프로시저 부분만 수정하면 프로그램 업데이트 없이 간편하게 오류 패치가 되서 이점이 크다’ 라고 말씀하시는 분들도 계시는데
그런 환경은 CI/CD 구축이 제대로 되어 있지 않다 라고 말하는 것과 동일하다고 생각합니다.
CI/CD 가 제대로 되어 있다면 프로그램 수정 후 배포의 과정은 그렇게 귀찮거나 오래 걸리지 않을테니깐요.
캐싱의 효익은 쿼리에만 있고, 모든 쿼리는 캐싱의 효익을 누리는지요? → MSSQL 기준, 모든 쿼리는 실행되기 전에 쿼리 계획이 만들어 집니다. 쿼리 계획이 만들어 지는 비용이 큰 경우 해당 쿼리는 '느리다’라고도 말 할 수 있습니다.
최초 실행 된 쿼리는 성능 향상을 위해 쿼리 계획을 캐시 테이블에 별도로 관리 합니다.
또한 자주 사용되는 쿼리는 더 오랜 기간동안 캐시가 유지 됩니다.
이후 대/소문자 포함, 공백 포함 등 쿼리 구문이 같다면 캐시된 계획을 사용하기 때문에 분석 단계를 하지 않고 바로 실행 되기에 저장 프로시저와 비교해서 속도가 느리지 않습니다.
이 과정은 저장 프로시저도 동일 합니다. 저장 프로시저도 마찬가지로 최초 실행될때 실행 계획이 분석되어 캐싱 처리 되는데 저장 프로시저는 보통 대/소문자 공백 등 쿼리가 변경될 가능성이 적기 때문에 가급적 캐시를 사용하게 되므로 더 나은 성능이라고 볼 수 있을 수 도 있지만, 마찬가지로 저장 프로시저 또한 변경이 자주 일어 난다면 최초 실행되는 일반 쿼리 성능과 동일하다고 볼 수 있습니다. 물론 미세하게나마 빠른 성능이 있을 순 있겠지만 의미 없는 차이라고 생각합니다.
단순한 관리의 문제 아닐까요? → 예시를 든 구문에만 꽂히신든 합니다.
제가 말하고 싶은 것은 ‘형상 관리가 어렵다’ 입니다. 따로 저장 프로시저만 형상관리를 하게 된다면 그 또한 관리 포인트가 늘어 난다는 점입니다.
※ 참고로 제가 경험이 많진 않지만 중.소 / 중견 기업에 이직 해본 단순 저의 경험으로 실제로 저렇게 관리 되는 회사가 적지 않았습니다.^^
ORM 과 저장 프로시저가 상호 대체적이었으나 지금도 그렇다고 볼 수 있을까요? → ORM과 저장 프로시저가 상호 대체적 이었다는 말이 공감 되지 않습니다. 단편적으로 판단될게 아닌 듯 합니다.
저장 프로시저는 로직을 포함할 수 있지만, 코드와 협업 할 경우, 로직을 저장 프로시저(데이터 레이어)에 포함시키는 것은 안티 패턴 아닌지요? → 질문 의도를 제가 이해를 잘 못했습니다. 저장 프로시저를 사용할 경우 로직이 저장 프로시저에 포함될 가능성이 있기에 그 가능성을 열어두지 말자 입니다.
저장 프로시저가 관리 및 성능에 있어 만능 이라면 모든 데이터 조작은 모두 저장 프로시저로 사용 해야 되는거 아닐까요 ?
그런데 그렇지 않고, 보편적으로 저장 프로시저를 사용하는 이유는 마수리님 저의 답변 글 처럼 ‘복잡해서, 어쩔 수 없는 환경’ 때문에 사용 되어지고 있습니다.