Offcanvas

How To / 개발자 / 데이터센터 / 애플리케이션

더 빠른 SQL 쿼리를 위한 21가지 데이터베이스 튜닝 규칙

2017.07.31 Sean McCown  |  InfoWorld


8. SQL 서버에서 분할(Partition)을 활용하라
SQL 서버 엔터프라이즈 사용자들은 성능을 가속화하기 위해 데이터 엔진의 자동 분할 기능을 활용할 수 있다. SQL 서버에서는 간단한 테이블조차도 하나의 분할로 생성되며, 사용자는 나중에 그것을 필요에 따라 여러 개의 분할로 쪼갤 수 있다. 테이블 간에 많은 양의 데이터를 옮겨야 할 경우, INSERT와 DELETE 문 대신에 SWITCH 명령을 사용할 수 있다. 테이블 간에 많은 양의 데이터를 삭제하고 삽입하는 대신, 단일 테이블에 대한 메타데이터만 변경하는 것이기 때문에, 실행하는데 몇 초 밖에 걸리지 않는다.

9. 배치 모드로 삭제(Delete)와 갱신(Update) 작업을 하라
거대한 테이블에서 많은 양의 데이터를 삭제하거나 업데이트하는 작업은 악몽일 수 있다. 문제는 이 두 가지 명령문 모두가 하나의 트랜잭션으로 실행되는 것이며, 프로세스를 중지시켜야 한다거나 작업 도중에 어떤 일이 일어진다면, 시스템은 전체 트랜잭션을 복원(Roll Back)시켜야만 한다. 이 작업은 진행 중인 다른 트랜잭션들을 블록 시킬 뿐 아니라, 많은 시간이 걸릴 수 있어서, 기본적으로 시스템 병목을 일으킨다.

해결책은 작은 배치 단위로 삭제나 업데이트 작업을 하는 것이다. 트랜잭션이 중지돼도, 소수의 행만 복원하면 되므로, 데이터베이스는 훨씬 더 빨리 온라인으로 돌아온다. 그리고 더 작은 배치작업들이 디스크에 커밋(Commit)하는 동안, 다른 작업들이 끼어들어서 어느 정도의 작업을 할 수 있어서 동시성이 크게 개선된다.

10. 서두르지 말고 천천히 하라
일부 개발자들은 이런 삭제와 업데이트 작업이 같은 날 완료되어야만 한다는 사실을 머리 속에 새겨놓고 있다. 늘 그런 것은 아니다. 특히, 아카이빙 작업은 더욱 그렇지 않다. 이 작업은 필요한 만큼 늘일 수 있으며, 이 작업을 완료하는 데는 더 작은 배치작업들이 도움이 된다. 이런 집약적인 작업을 더 천천히 할 수 있다면, 여분의 시간을 시스템이 다운되지 않도록 하는 데 투여하기 바란다.

11. ORM을 피하라
ORM(Object-relational Mapper: 객체 관계형 매퍼)는 지구상에서 최악의 코드를 만들어 내고 있으며, 개발자가 직면할 가능성이 있는 대부분의 성능 문제에 책임이 있다. 그렇지만, ORM을 피할 수 없다면, 스스로 자체적인 저장 프로시저를 작성하고 ORM이 자체 쿼리를 작성하는 대신 사용자가 작성한 쿼리를 호출하게 함으로써 부정적인 측면을 최소화할 수 있다.

12. 가능한 경우, 저장 프로시저(Stored Procedure)를 사용하라
더 훌륭한 코드로 이끄는 것 외에, 저장 프로시저는 다른 많은 장점도 가지고 있다. 저장 프로시저는 호출이 더 짧을 것이기 때문에, 트래픽을 크게 줄여준다. 프로파일러(Profiler) 같은 도구를 사용해서 추적하기가 더 쉬워서 사용자가 성능 통계치를 확보하고 잠재적인 문제를 더 빨리 규명할 수 있게 해준다. 더욱 일관성 있는 방식으로 정의할 수 있으며, 이는 실행 계획(Execution Plan)을 재사용할 가능성이 더 높으며, 임의 쿼리에 비해 엣지 케이스(Edge Case)와 감사용으로 사용하기가 더 쉽다는 의미이다.

많은 닷넷 코더들은 비즈니스 로직이 데이터베이스가 아닌 애플리케이션의 프론트 엔드에 속한다고 믿고 있다. 그렇지만, 그들은 틀렸다(대부분의 경우).

13. 더블 디핑(Double-Dipping: 중복 처리)을 피하라
저장 프로시저 사용은 때로 “더블 디핑”으로 이어질 수 있다. 대규모 테이블에 대해 별개의 쿼리를 여러 개 실행하고, 그것들을 임시 테이블에 넣은 다음에, 테이블들을 다시 조인하는 것이다. 이는 성능에 커다란 방해물이 될 수 있다. 가능한한 대규모 테이블을 한 번만 쿼리 하는 것이 훨씬 더 낫다.

조금 다른 시나리오는 한 프로세스의 몇 가지 단계에서 커다란 테이블의 일부가 필요한 경우로, 이는 매 번 커다란 테이블에 대한 쿼리를 유발한다. 일부에 대한 쿼리를 실행하고 그것을 다른 곳에 영속화 시킨 다음에, 후속 단계를 영속화된 더 작은 데이터 세트로 유도하라.

14. 커다란 트랜잭션은 작은 트랜잭션 여러 개로 쪼개라
단일 트랜잭션에서 여러 개의 테이블을 처리하는 작업은 해당 트랜잭션이 끝날 때까지 모든 테이블을 잠글 수 있기 때문에, 다수의 블로킹으로 이어진다. 해결책은 이 트랜잭션을 각각이 개별적으로 단일 테이블에 대한 작업을 하는 여러 개의 루틴(Routines)으로 쪼개는 것이다. 이는 블로킹 횟수를 줄여주고 다른 작업들이 계속해서 이루어질 수 있도록 다른 테이블들을 풀어준다.

15. 트리거(Trigger) 사용을 자제하라
하려고 하는 작업이 무엇이든, 원래 작업의 동일한 트랜잭션에서 수행될 것이기 때문에 트리거 사용도 비슷한 문제로 이어질 수 있다. 이는 트리거가 완료될 때까지 여러 개의 테이블을 잠그는 결과를 초래할 수 있다는 의미이다. 이런 트리거를 별개의 트랜잭션들로 쪼개면 더 적은 수의 자원을 잠그게 돼서 필요한 경우 변경사항 복원을 쉽게 만들어준다. 가능하면 트리거를 피하라.

CIO Korea 뉴스레터 및 IT 트랜드 보고서 무료 구독하기
추천 테크라이브러리

회사명:한국IDG 제호: CIO Korea 주소 : 서울시 중구 세종대로 23, 4층 우)04512
등록번호 : 서울 아01641 등록발행일자 : 2011년 05월 27일

발행인 : 박형미 편집인 : 천신응 청소년보호책임자 : 한정규
사업자 등록번호 : 214-87-22467 Tel : 02-558-6950

Copyright © 2024 International Data Group. All rights reserved.