전체 글 썸네일형 리스트형 MySQL OR 조건과 인덱스 - OR 때문에 쿼리가 느려지는 이유 SQL을 작성하다 보면 이런 조건을 자주 만나게 됩니다.SELECT *FROM usersWHERE status = 'active' OR status = 'pending';또는 서로 다른 컬럼을 비교하기도 합니다.SELECT *FROM usersWHERE email = 'test@example.com' OR phone = '010-1234-5678';문법적으로는 아무런 문제가 없습니다.그런데 데이터가 많아지고 인덱스가 추가되면서 이런 질문이 생깁니다.OR을 사용하면 인덱스를 제대로 사용할 수 있을까?인터넷을 찾아보면 흔히OR은 인덱스를 못 타기 때문에 느리다.라는 이야기도 볼 수 있습니다.하지만 이것은 너무 단순한 설명입니다.MySQL은 OR 조건에서도 상황에 따라 인덱스를 사용할 수 있습니다.중요.. MySQL DISTINCT 제대로 이해하기 - 중복 제거가 왜 느려질까? SQL을 작성하다 보면 이런 상황을 자주 만나게 됩니다.SELECT DISTINCT user_idFROM orders;주문 테이블에 같은 사용자의 주문이 여러 개 있다면 user_id가 여러 번 나타날 수 있습니다.DISTINCT는 이런 중복을 제거해서 한 번씩만 보여줍니다.처음에는 굉장히 간단해 보입니다.그런데 데이터가 많아지면 이런 질문이 생깁니다.DISTINCT는 내부적으로 어떻게 중복을 제거할까?그리고 다음과 같은 쿼리는 어떨까요?SELECT DISTINCT users.*FROM usersJOIN orders ON orders.user_id = users.id;JOIN 결과에서 중복된 사용자를 없애기 위해 DISTINCT를 붙인 것입니다.물론 결과는 원하는 대로 나올 수 있습니다.하지만 왜 .. MySQL BETWEEN과 범위 검색 제대로 이해하기 - 인덱스는 어떻게 범위를 찾을까? MySQL에서 특정 기간의 데이터를 조회할 때 다음과 같은 SQL을 자주 사용합니다.SELECT *FROM ordersWHERE created_at BETWEEN '2026-08-01' AND '2026-08-31';문법도 간단하고 읽기도 쉽습니다.그런데 한 가지 궁금한 점이 생깁니다.BETWEEN은 실제로 어떻게 데이터를 찾을까요?그리고 다음 조건은WHERE created_at BETWEEN ...다음과 어떤 차이가 있을까요?WHERE created_at >= ... AND created_at 더 중요한 것은 created_at에 인덱스가 있다면 MySQL은 이 범위를 인덱스에서 어떻게 찾느냐는 것입니다.이번 글에서는 BETWEEN 자체의 문법만 설명하는 것이 아니라 범위 조건이 B-Tree 인덱스에.. MySQL 함수 때문에 인덱스를 못 타는 경우 - WHERE 조건을 어떻게 작성해야 할까? MySQL에서 날짜를 검색하다 보면 이런 쿼리를 자주 작성하게 됩니다.SELECT *FROM ordersWHERE DATE(created_at) = '2026-08-31';의미는 명확합니다.created_at에서 날짜 부분만 가져와서 2026-08-31인지 확인하는 것입니다.그런데 created_at에 인덱스가 있다면 어떨까요?CREATE INDEX idx_orders_created_atON orders (created_at);인덱스까지 만들어 놨는데도 쿼리가 기대만큼 빨라지지 않는 경우가 있습니다.왜 그럴까요?핵심은 WHERE 조건에서 컬럼에 함수를 적용하고 있다는 것입니다.이번 글에서는 실제 SQL을 통해 다음 두 가지 조건을 비교해보겠습니다.WHERE DATE(created_at) = '2026-0.. MySQL LIKE 검색과 인덱스 - 어떤 검색은 왜 인덱스를 못 탈까? 웹 서비스를 개발하다 보면 검색 기능을 정말 자주 만들게 됩니다.예를 들어 회원 이름을 검색한다고 해보겠습니다.SELECT *FROM usersWHERE name LIKE '김%';또는 사용자가 입력한 단어가 이름 어디에 포함되어 있는지 찾기 위해 다음과 같이 작성할 수도 있습니다.SELECT *FROM usersWHERE name LIKE '%김%';둘 다 LIKE를 사용하고 있기 때문에 비슷하게 보입니다.그런데 데이터가 많아지면 두 쿼리의 성능이 달라질 수 있습니다.특히 name 컬럼에 인덱스가 있어도WHERE name LIKE '김%'와WHERE name LIKE '%김%'는 인덱스를 활용하는 방식이 다릅니다.그렇다면 왜 이런 차이가 발생할까요?이번 글에서는 LIKE 검색이 B-Tree 인덱스와 어.. 배포할 때마다 5개월 전 CSS로 되돌아가던 버그를 Linux stat으로 추적한 이야기 배포할 때마다 랜딩 사이트의 CSS가 예전 상태로 되돌아가는 문제가 있었다.가격 안내 페이지를 개편해서 배포했고, 배포 직후 확인했을 때는 정상적으로 보였다.그런데 며칠 뒤 다시 들어가 보니 스타일이 통째로 깨져 있었다.그 사이에 별도의 배포를 한 기억도 없었다.서버에서 프론트 에셋 빌드를 다시 돌리니 바로 복구됐다.빌드 한 번으로 복구되는 건 다행이었지만 더 중요한 문제가 있었다.왜 깨졌는지, 언제부터 깨졌는지를 알 수 없었다.원인을 모르면 다음 배포에서도 똑같은 문제가 발생할 수 있다.그래서 파일의 생성 시각과 수정 시각부터 하나씩 추적해보기로 했다.환경이번 문제의 환경은 다음과 같았다.LaravelLaravel Mix (webpack)빌드 산출물은 public/assets에 생성public/asse.. MySQL LIMIT 성능 제대로 이해하기 - LIMIT 20인데 왜 느릴까? 웹 서비스에서 목록을 조회할 때 LIMIT은 거의 항상 사용됩니다. SELECT *FROM ordersORDER BY created_at DESCLIMIT 20; 최근 주문 20개만 가져오는 아주 평범한 쿼리입니다.그런데 데이터가 많아지면 이런 의문이 생깁니다.100만 건 중에서 20개만 가져오는데 왜 느릴까?LIMIT 20이라고 해서 MySQL이 처음부터 20개의 데이터만 읽는 것은 아닙니다.특히 ORDER BY와 함께 사용될 경우 어떤 인덱스를 사용하느냐에 따라 MySQL이 처리해야 하는 데이터의 양이 크게 달라질 수 있습니다.이번 글에서는 LIMIT이 실제로 어떻게 동작하는지 확인하고, ORDER BY와 인덱스를 함께 사용했을 때 왜 성능 차이가 발생하는지 살펴보겠습니다.목차LIMIT은 정말 20건.. MySQL ORDER BY와 인덱스 - Using filesort가 발생하는 이유 MySQL에서 데이터를 조회할 때 WHERE 조건만큼 자주 사용하는 것이 ORDER BY입니다.예를 들어 최근 주문부터 조회한다고 해보겠습니다. SELECT id, user_id, amount, created_atFROM ordersWHERE user_id = 1ORDER BY created_at DESC; 데이터가 적을 때는 문제가 없어 보입니다.하지만 주문 데이터가 수백만 건으로 늘어나면 이야기가 달라집니다.특히 다음과 같은 실행 계획을 확인하다 보면:Using filesort 라는 내용을 만나게 됩니다.이름 때문에 디스크에 파일을 만들고 정렬하는 것처럼 생각하기 쉽지만, 정확히는 MySQL이 인덱스의 정렬 순서를 그대로 이용하지 못하고 별도의 정렬 작업을 수행한다는 의미로 이해.. 이전 1 2 3 4 ··· 8 다음