운영 DB에서 특정 화면이 느리다는 제보를 받으면, 저는 제일 먼저 쿼리부터 봅니다. 그런데 쿼리를 열어보면 십중팔구 이런 반응이 나옵니다. "어? 이거 인덱스 있는데?" 인덱스가 있다는 것과 인덱스를 탄다는 것은 완전히 다른 얘기입니다. 이 차이를 모르면 인덱스를 아무리 추가해도 쿼리는 계속 느립니다.이번 글은 제가 실무에서 반복적으로 만난 "인덱스가 있는데도 안 타는" 케이스들을 MySQL 기준으로 정리한 것입니다. 대부분 EXPLAIN 한 번이면 원인이 보이는 것들인데, 처음 겪으면 한참 헤매게 되는 유형들입니다.사진: Unsplash의 Growtika먼저 EXPLAIN 읽는 법부터, 딱 세 컬럼만실행계획을 처음 보면 컬럼이 많아서 부담스러운데, 실무에서 문제를 잡을 때 제가 먼저 보는 건 딱 세 ..
목록 화면을 만들 때 가장 먼저 손이 가는 게 LIMIT ... OFFSET ... 이다. 프레임워크가 다 해주니까 신경 쓸 일도 없다. Laravel이면 paginate() 한 줄이고, 페이지 번호는 알아서 붙는다.문제는 데이터가 쌓이고 나서 터진다. 개발 초기에 1,000건으로 테스트할 때는 멀쩡하던 목록이, 운영 6개월 차에 수십만 건이 되면 뒤쪽 페이지에서 눈에 띄게 느려진다. 그리고 느려지는 것보다 더 골치 아픈 문제가 하나 더 있다.문제 1. 뒤로 갈수록 느려진다OFFSET 100000 LIMIT 20 을 DB가 어떻게 처리하는지 생각해보면 답이 나온다. DB는 100,000건을 건너뛰는 게 아니라, 100,020건을 실제로 읽은 다음 앞의 100,000건을 버린다. 건너뛴다는 표현이 주는 인..
AWS RDS 비용 줄이는 방법 및 최적화 하기 서론 ( 안 읽어도 됨) 현재 필자가 다니는 회사는 예약관리 서비스를 하고 있습니다. 처음 입사 했을 때는 사용자가 그리 많지 않아서 T시리즈를 이용해도 문제가 없었지만, 입사 후 갑자기 폭팔적인 서비스 성장으로 인해 순간 동접 1만을 넘는 거대한 서비스가 되었고, 현재 해당 분야 업계 1위가 되었습니다. 서비스 성장은 언제나 즐겁지만, 스타트업들의 개발 코드는 여기서부터 문제입니다. 서비스를 위한 기능 추가만 하다보니 코드가 그렇게 깔끔하지 않을 뿐더러, ORM 코드들의 최적화되지 않은 쿼리도 문제였습니다. 이 문제는 우리 회사도 다르지 않았습니다. 처음 MariaDB 를 사용하고 있었는데.. DB 의 CPU 가 90프로를 넘기는 경우가 종종 있었고, 업..
MariaDB 빠르게 백업하고 복원하기 이번에 RDS mariadb 에서 RDS auroradb 로 이전하게 되었다. 한달에 회원이 1~2만명 씩 꾸준히 늘어나고 있고, 피크 타임, 이벤트 타임 때 DB를 유연하게 움직이기 위해서 mariadb 를 보내줘야 했기 때문이다. 문제는 데이터가 너무 많았다. 물론 초대형 사이티들의 테라급은 아니지만, 적어도 내 경험 (이력) 에서 가장 많은 데이터다. 그냥 무작정 툴로 QA 서버를 백업과 복원을 했더니 4시간이 넘게 걸렸다. (우리는 production 서버의 한달 전 데이터가 staging, staging 의 한달전 데이터가 QA 다) 아무런 옵션 없이 하는 것은 무식한 짓인 것을 깨달아 경험을 공유할겸 나중에 내가 보고 다시 하려고 적어둔다. --no-au..
사용자 테이블에서 휴대폰 번호가 안 들어간 행을 찾으려고 IS NULL을 걸었는데 아무것도 안 나온 적이 있다. 분명 화면에는 비어 보이는데 말이다.원인은 단순했다. 그 컬럼에 들어 있던 건 NULL이 아니라 빈 문자열이었다. IS NULL 같은 문법이 있을 줄 알고 IS EMPTY를 찾았는데, 그런 건 없고 그냥 이렇게 하면 된다.SELECT * FROM users WHERE mobile = '';NULL과 빈 문자열은 완전히 다른 값이다둘 다 "값이 없다"처럼 보이지만 DB 입장에서는 전혀 다르다.NULL: 값이 존재하지 않음. "모른다"에 가깝다.빈 문자열(''): 길이가 0인 문자열이라는 값이 존재한다.그래서 이런 결과가 나온다.SELECT NULL = ''; -- NULL (true..
