내맘대로 정리하는 Real MySQL #16 #17장) 베스트 프랙티스와 응급처치
<내맘대로 정리하는> 시리즈는, 책을 읽으며 몰랐던 내용을위주로 정리한 내용 그대로 포스팅하는 시리즈입니다 ^^
원문의 문맥이 궁금하면 (좋은 책이니) 이 참에 하나 장만하는 것은 어떤가요??
16장. 베스트 프랙틱스
임의 정렬
기준을 아무것도 적용하지 않은 임의의 순서대로 가져오는 방법
SELECT * FROM tb_member
ORDER BY RAND()
LIMIT 1;
- record 건수나 WHERE로 걸러진 record 건수가 많다면 문제될 수 있다.
인덱스를 사용한 임의 정렬
임의의 정수 필드를 테이블에 항상 랜덤하게 추가 저장한다. 이 column에 index를 걸어 램던 조회시 random 값을 하나 골라 그 보다 큰 것 3개, 작은 것 3개를 가져와 union을 건다
페이징
인덱스를 사용한다 하더라도 계속해서 다음 페이지로 넘어가면 조금씩 조회 쿼리가 느려질 수 밖에 없다. 단순히 LIMIT의 오프셋만 변경해 다음 페이지의 레코드를 조회하는 쿼리는 실제 필요하지 않은 레코드까지 모두 읽는 방식으로 처리된다.
불필요한 읽기 작업을 제거하려면 페이징 쿼리를 실행할 때 게시물 테이블의 PK를 SELECT 쿼리 조건절에 넣어주어야 한다. (no offset 방식)
MySQL에서의 시퀀스
- 시퀀스용 테이블은 절대 InnoDB와 같이 트랜잭션을 지원하는 스토리지 엔진을 사용하면 안 된다.
- 복제가 구축된 환경의 MySQL 서버에서는 이 시퀀스로부터 일련번호를 읽음과 동시에 그 값을 다른 테이블에 INSERT 해서는 안 된다
큰 문자열 칼럼 해시
가끔 매우 긴 문자열을 저장하는 칼럼에 대해 인덱스를 생성하거나 검색을 수행해야 할 때, 긴 문자열의 해시 값으로 PK나 Unique 인덱스를 생성하면 쉽게 해결할 수 있다.
타임라인
타임라인 기능은 두 가지 측면에서 RDBMS에 적합하지 않은 데이터라고 볼 수 있다.
- RDBMS는 쓰기는 느리지만 읽기는 빠르게 처리하는 것이 장점이자 특성인데, 타임라인 기능은 읽기보다 쓰기의 비중이 훨씬 많다. 타임라인의 이런 특성은 사용자의 수나 관계가 불어날수록 더 심해진다.
- RDBMS의 정렬은 인덱스를 이용하지 못하면 정렬 대상 건수에 비례해 상당히 느려질 수밖에 없는데, SNS의 타임라인의 정렬은 인덱스를 이용할 수 없다. 사실 이는 RDBMS의 특성이라기 보다 현재 사용되는 하드웨어의 한계로 인한 모든 SW 특성이라 볼 수 있다.
RDBMS의 이런 문제점을 해결하기 위해 NoSQL이라고 불리는 읽기보다 쓰기 위주의 DB가 등장하기 시작했다.
SQL 작성 팁
- 조인 조건은 항상 ON절에 기재
- 테이블 별칭 사용 및 칼럼 명에 테이블 별칭 포함
- 서브쿼리는 조인으로 변경
- UPDATE, DELETE 쿼리와 적용 건수 꼭 체크하기
스키마 체크
SELECT table_schema, table_name, column_name,
column_type, character_set_name, collation_name
FROM information_schema.columns
WHERE table_schema = 'employees';
17장. 응급처치
서버 과부하
사용자의 수가 늘어나는 부분에 대비해서 MySQL 서버가 평상시에는 대략 2~30%의 자원만 사용하도록 유지하기도 한다. 어떤 원인이든지 MySQL 서버의 과부하 상태로 인해 어떤 쿼리도 처리하지 못하고 OS에 로그인도 할 수 없는 상황이라면 장비 자체를 재시작하는 것이 좋다.
- 서버에 접속해 하드웨어 상태를 확인하는 것이 좋다.
- CPU : uptime 명령어, vmstat
- Memory :
free -m -t
일반적으로 리눅스 계열 OS는 물리적 메모리의 가능한 최대 여유 공간을 OS의 버퍼나 캐시공간을 활용하기 때문에 free에 표시되는 메모리 크기는 전체 물리적 메모리의 1% 미만일 때가 많다. - Disk :
iostat -dx 1
에러 로그가 너무 크다면 유닉스의 less 명령어를 사용해 파일의 마지막 부분만 열어 보는 것이 가능하다.