본문 바로가기

Development Note

[MYSQL] 쿼리 작성 및 최적화

336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

 전반적인 쿼리 작성 방법에 대해서 엄청난 분량으로 나와 있다. 대략 한 150 페이지 정도 되는데 그 디테일이 엄청 나다. 단순히 기능에 대한 설명 뿐만 아니라 성능과 그 동작 메카니즘까지 설명하고 있으니 보고 있으니 머리가 아프기도 하고 한편으로는 신기하기도 하다. 진작에 이런 데이터 베이스의 동작 구조에 대해서 알고 있었더라면 좋았겠다. 싶다. 글을 쓰면서 학창 시절 DB 관련 수업 학점이 문득 떠오른다. 그럴만한 이유가 있다.


크게 쿼리 작성과 관련하여 함수, SELECT, INSERT, UPDATE, DELETE 와 같은 주요 키워드에 대한 부연 설명들이 많다. 당연히 SELECT 가 그 비중이 가장 큰데 실제 이 단락의 내용은 이게 다라고 봐도 될 정도로 엄청나게 많은 분량이다. 하나하나 다 설명하기에는 곤란한 분량이기 때문에 책에 있는 내용들을 외우거나 완벽히 이해하는 수준은 아니라도 한번쯤은 다 봐야 한다고 생각한다.


이 챕터의 내용은 쿼리 작성만이 주된 것이 아니다. 그러다보니 문법을 어떻게 사용하느냐를 이야기 하고자 하는게 아니라 최적화에 대한 것들을 항상 고려하면서 설명을 짓고 있다. 최적화라는 어휘를 영문으로 만들면 Optimization 인데 SQL Optimizer 라는 것이 얼마나 효율적으로 동작을 만들어 내야 하는지가 주된 내용이 된다. 그러기 위에선 앞서 실행 계획에 대한 기반 지식을 습득한 것이 더욱 도움이 되었다. 주된 내용들 중에 인상 깊은 내용들을 정리해 보면 다음과 같다.


1. COUNT() 함수

 - COUNT(*) 함수는 인덱스를 제대로 사용하도록 되어 있지 않다면 생각보다 많은 부하를 일으킬 수 있다. 특히 WHERE 절이 존재 하는 경우에도 신경을 써야 한다.


2. BENCHMARK() 함수

 - 쿼리의 성능 테스트하고는 다소 거리가 멀다. 동일 기능을 분석하는 정도로 쓰는게 좋다.


3. WHERE, GROUP BY, ORDER BY 의 인덱스를 사용하기 위한 규칙

 - 특정 칼럼에 대해서 변형한 값에 대한 비교의 경우에는 인덱스를 사용할 수 없다.

 - 데이터 타입이 다른 경우에도 인덱스를 활용하지 못한다.

 - 가급적 OR 연산자를 사용하지 않는 것이 좋다.


4. LIMIT

 - 오라클의 ROWNUM 이나 MSSQL 의 TOP 과 기능은 유사하지만 동작 방식이 다소 다르다.

 - 정렬이나 그루핑이 없는 경우에는 성능면에서 이득을 볼 수 있으나 두 경우가 있는 때는 그렇지 않다.

 - 커넥션 풀에서 커넥션의 유효성을 확인 하기 위해서 "LIMIT 0" 을 사용하기도 한다.


5. JOIN

 - Optimizer 가 드라이빙 테이블과 드리븐 테이블을 선택하여 조인 순서를 정한다. (이 선택이 최적일때가 많다)

 - 인덱스 사용에 영향을 미치는 경우는 데이터 타입의 불일치나 문자열, 콜레이션이 다른 경우에도 이런 문제를 일으킬 수 있다.


6. SUBQUERY

 - MYSQL 서버는 서브 쿼리를 최적화시키지 못할 때가 더 많다.

 - IN 연산자와 함께 사용할 때는 효율적으로 처리되지 못한다.

 - 다만 서브쿼리가 인덱스를 잘 활용할 수 있다면 크게 주의할 사항은 없다.


또한 몇 가지 새로운 점들은 UPDATE, INSERT, DELETE 에 대한 추가적인 기능 사용들에 대해서도 명시가 되어있다. 단순히 값을 수정, 삭제, 지우는 것에 그치는 것이라 PK 가 중복 되는 것에 대해 UPDATE 처리를 할 수 있는 INSERT 라던가 서브 쿼리를 통해서 기능을 더욱 풍부하게 할 수 있는 방법들에 대해서 배우게 되었다. LIMIT 키워드를 응용하여 랭킹같은 것들을 처리할 수 있는 팁에 대한 내용도 볼만 하다.



왜 관계형 데이터 베이스라고 불리는지에 대한 이유를 알게 되었다.



해당 페이지를 다 읽어 보고 난 뒤의 소감은 다음과 같다.


1. 여러 가지 최적화를 위한 쿼리 방법들이 있지만 그 핵심은 인덱스를 사용하는 것이 아닐까?


2. 동작 순서와 메카니즘을 알고 많은 경험이 있어야 실제 쿼리에 대한 튜닝이 가능하다.


3. 성능의 개선이라는 것은 대용량의 데이터를 다룰때 더 큰 의미가 있다. (즉 수백, 수천건의 레코드를 가지고는 딱히 고민할 필요가 없을 것 같다.)