1. 작게 생각하기
: 규모가 커질 것을 고려하여 설계 해야함
: 확장이 가능하도록 아키텍처를 잘 쪼개야하며, 복제와 파티셔닝에 대해 미리 계획을 세울 것
2. EXPLAIN 안써보기
: 쿼리 실행 전 반드시 EXPLAIN으로 쿼리의 성능을 확인해볼 것
3. 잘못된 데이터 타입 선택
: 한 메모리 블럭 단위에 인덱스 레코드가 많이 들어갈수록 쿼리가 빨리 실행된다
: 가장 작은 데이터 타입을 선택할 것
: 인덱스 걸리는 필드는 최소한의 데이터 크기로 선택해야함
4. PHP에서 poconnect 사용
: 아파치에서 좀비 프로세스가 발생하면 커넥션이 증발해버림
: MySQL의 접속 속도는 Oracle이나 PostgreSQL보다 더 빠름
5. 너무 과도한 DB 추상화 계층을 두는 것
: scale out 가능한 계층만 둘 것
6. 스토리지 엔진을 이해하지 못하는 것
: 단일 엔진만으로 전체 아키텍처를 결정한 경우 최적화가 아닌 경우가 많다
: 엔진 별 장단점을 공부할 것
7. 인덱스 레이아웃을 이해하지 못하는 것
: 인덱스와 스토리지 엔진을 제대로 이해할 것
: 엔진은 데이터와 인덱스 레코드를 메모리나 디스크에 레이아웃 하는 것의 구현체
: clusterd / non-clustered 구성에 대해 공부할 것
8. 쿼리 캐시를 이해하지 못하는 것
: 애플리케이션의 read/write 비율을 꼭 알도록 하자
: 쿼리 캐시 설계는 CPU 사용과 읽기 성능간의 타협
: 자주 변하는 것과 변하지 않는 것을 쪼개는 것이 중요
9. Stored Procedure를 사용하는 것
: MySQL은 다른 RDBMS와 다르게 connection thread에서 실행 계획이 세워짐
: 데이터를 한 번 가져오고 연결을 끊으면 CPU 성능을 낭비하는 것이 됨
10. 인덱스 컬럼에 함수 사용
: 함수에 인덱스 컬럼을 넣어 호출하면 인덱스를 못탄다
: 함수를 먼저 계산해서 상수로 만든 다음 = 로 연결해야 인덱스를 탈 수 있음
11. 인덱스를 쓰지 않거나 쓸모없는 인덱스를 만들어 놓는 것
: 쓸모없는 인덱스는 INSERT/UPDATE/DELETE를 느리게 만듦
: FK에 대해서는 반드시 인덱스를 걸어라
: WHERE 이나 GROUP BY 표현식에서 쓰이는 컬럼은 인덱스 추가를 고려할 것
: covering index 사용을 고려할 것
: 인덱스 컬럼 순서에 유의할 것
12. JOIN을 사용하지 않는 것
: 서브쿼리는 JOIN으로 재작성 하자
: 커서는 제거하자
13. Deep Scan을 고려하지 않는 것
: 전체 집합을 정렬한 다음 LIMIT으로 가져오면서 느려질 수 있다
: 어떻게든 집합을 작게 줄인 다음 LIMIT을 걸어 가져올 것
14. InnoDB 테이블에서 WHERE 조건절 없이 SELECT COUNT(*)
: InnoDB 테이블에서는 이렇게 하면 느림
: 각 레코드의 transaction isolation을 유지하는 MVCC 구현이 복잡하기 떄문
: 트리거를 걸어서 메모리 스토리지 엔진 쓰는 테이블에 통계를 별도로 유지
15. 프로파일링이나 벤치마킹을 하지 않는 것
: 프로파일링 = 병목 찾아 내기
: 벤치마킹 = 시간에 따른 성능 변화 추이 평가. 부하 테스트
: /path/to/log에서 log_slow_queries 및 log_queries_not_using_indexes를 기록하게 할 것
: EXPLAIN / SHOW PROFILE / MyTop / innotop / musqlslap / MyBench / Slow Query Log 등의 도구를 사용할 것
16. AUTO_INCREMENT를 사용하지 않는 것
: 특히 PK에 최적화 되어있으므로 PK에는 되도록 사용할 것
: LOCK 걸리지 않으면서 읽을 수 있음
17. ON DUPLICATE KEY UPDATE를 사용하지 않는 것
: 서버에 불필요하게 요청하고 응답하는 과정을 줄일 수 있음
: 5~6%정도의 성능향상 가능
최종 정리
Thinking too small
Not using EXPLAIN
Choosing the wrong data types
Using persistent connections in PHP
Using a heavy DB abstraction layer
Not understanding storage engines
Not understanding index layouts
Not understanding how the query cache works
Using stored procedures improperly
Operating on an indexed column with a function
Having missing or useless indexes
Not being a join-fu master
Not accounting for deep scans
Doing SELECT COUNT(*) without WHERE on an InnoDB table
Not profiling or benchmarking
Not using AUTO_INCREMENT
Not using ON DUPLICATE KEY UPDATEK
Reference
'Database > MySQL' 카테고리의 다른 글
MySQL에서 JSON 데이터 사용하기 (0) | 2023.05.29 |
---|---|
MySQL DB 및 테이블 용량 확인 (information_schema.tables) (0) | 2023.05.15 |
MySQL 테이블 수정 간단정리 (0) | 2023.01.30 |
MySQL 실행 계획 (0) | 2022.10.30 |
MySQL 인덱스 생성 수정 / 삭제 (0) | 2022.10.30 |