Skip to content
isdnetworks
Go back

앱이 실제로 만드는 SQL로 봐야 한다

느린 검색을 개선하려고 인덱스를 셋 설계해서 추가하고 배포까지 했다. 넣기 전에 실행계획으로 확인까지 했는데 체감 개선이 없다는 말을 들었다.

Table of contents

Open Table of contents

인덱스를 넣었는데 체감이 없었다

추가하기 전에 확인한 실행계획에서는 분명히 새 인덱스를 타고 있었다. 그러면 확인 자체가 잘못됐거나 확인한 것과 실제로 도는 것이 다르다는 뜻이다.

돌이켜 보니 내가 실행계획에 넣은 조건은 손으로 직접 쓴 것이었다. 그것이 앱이 실제로 만드는 조건과 같은지는 한 번도 확인한 적이 없었다.

손으로 쓴 조건과 앱이 만드는 조건

쿼리 빌더 코드를 따라가니 조건 하나가 두 항목을 묶은 형태로 조립되고 있었다. 내가 실행계획에 넣었던 조건에는 그 묶음 부분이 아예 없었다.

손으로 쓰면 핵심 조건만 남기고 무의식적으로 단순화하므로 인덱스가 잘 도는 것처럼 보인다. 실제 조건을 그대로 넣어 다시 돌리니 새 인덱스를 아예 안 타고 있었다.

OR가 막은 인덱스

두 항목을 묶은 조건이 각각은 인덱스로 찾을 수 있는데 하나로 묶이면 단일 인덱스로 커버가 안 된다. 옵티마이저는 정렬 순서를 얻을 수 있는 기본 키로 물러났다.

정렬과 개수 제한이 붙어 있으니 역순으로 훑다가 필요한 만큼 찾으면 멈추는 편이 낫다고 본 것이다. 인덱스가 있어도 조건의 형태가 그것을 못 쓰게 만든 경우였다.

거짓이던 설계 전제

인덱스를 설계할 때 마스터 상품은 특정 컬럼이 비어 있다는 전제를 깔고 있었다. 그 전제가 맞는지 실제로 세어 보니 해당 조합의 행이 하나도 없었다.

마스터 상품은 그 컬럼에 값이 들어 있었으므로 전제가 처음부터 거짓이었다. 틀린 전제 위에서 만든 인덱스라 조건을 못 좁히는 것이 당연한 결과였다.

절반을 넘는 조건과 세 방안

이 조건이 실제로 몇 건을 잡는지 세어 보니 전체의 절반을 넘었다. 절반을 넘게 잡는 조건은 인덱스로 좁혀지지 않으므로 인덱스를 더 넣어도 해결되지 않는다.

조건을 나눠 각각 인덱스를 타게 한 뒤 합치거나 병합이 가능하도록 별도 인덱스를 두거나 조건 자체를 계산 컬럼으로 만들어 거는 셋이 남았다. 인덱스 추가가 아니라 쿼리 구조나 스키마를 바꾸는 쪽으로 가야 하는 자리였다.

정리


Share this post on:

Previous Post
상대가 보는 하나뿐인 주소
Next Post
로그인 계정을 한 곳으로 모으면