Skip to content
isdnetworks
Go back

데이터를 숨긴 짧은 조회 최적화

(수정됨)

채팅 기록 messages 에서 접수된 이슈를 뽑는 작업을 했는데 결과를 검토하니 빠진 것이 많았다. 삭제로 제외된 메시지는 0건이고 방 커버리지는 천오백 건쯤 되는 전건이었는데도 이슈가 빠져 있었다.

Table of contents

Open Table of contents

원인 — 조회에서 잘라 뽑은 결과

조회 쿼리가 LEFT() 로 본문을 잘라서 가져오고 있었다.

SELECT LEFT(content, 600) AS content FROM messages ...

목록이 길어지니 화면에 담기 좋게 자른 것인데 이 시스템의 메시지는 길다. MySQL 8.0 참조 매뉴얼의 문자열 함수 항목대로 LEFT(str, len) 은 앞에서 len 글자만 돌려주고 나머지는 오류 없이 사라진다. 주문번호 목록과 상품번호 나열과 여러 항목이 묶인 보고가 오가고 MAX(LENGTH(content)) 를 보니 4천 자 가까운 것도 있다.

600자를 넘는 것이 수십 건이었고 그 수십 건에서 뒤쪽에 붙은 요청 문구가 통째로 빠졌다. 긴 목록 메시지는 앞부분이 번호 나열이고 마지막에 실제 요청이 붙으므로 앞에서 자르면 정확히 그 부분이 사라진다.

커버리지 지표의 한계

여기서 헷갈렸던 것은 전건을 읽은 것 자체는 사실이라는 점이다. 메시지 천오백 건쯤을 하나도 빼지 않고 처리했으니 커버리지 지표는 100%가 맞다. 그런데 각 메시지의 일부만 읽었다.

전부 읽었다는 것과 각각을 끝까지 읽었다는 것은 다른 얘기다. 커버리지 지표는 몇 건을 봤는지를 재고 각 건의 어디까지 봤는지는 재지 않는다. 두 축 중 한 축만 재고 있었으므로 지표는 정상이면서 결과는 빠질 수 있었다.

같은 형태의 두 사례

목록 태그를 안 걷는 파서가 있었다. 헬프센터 문서를 크롤링하는 코드가 h2·p·table 만 순회하고 ul·li 는 아예 처리하지 않아서, 안내 문구 대부분이 목록으로 된 페이지에서는 본문이 통째로 비었다. 내용이 div 로 한 겹 더 들어가 있으면 재귀로 파고들지도 않았다. 결과가 사실상 빈 캡처로 나왔는데 페이지에 내용이 없어서가 아니라 파서가 그 구조를 안 본 것이었다.

직계 자식만 보는 선택자도 있었다. 어떤 페이지의 목록 마크업이 ul 안에 ul 이 또 들어간 형태라 바깥 목록에 직계 li 가 하나도 없었다. querySelectorAll(':scope > li') 를 쓰니 빈 배열이 나왔는데 실제로는 링크가 십여 개 있었다.

셋의 공통점

읽는 범위를 좁힌 결정이 결과에서 보이지 않는다는 점이 같다. 잘라낸 조회도 결과가 나오고 목록을 안 걷는 파서도 결과가 나오고 직계만 보는 선택자도 결과가 나온다.

셋 다 오류가 아니라 부분 결과를 주고 그 부분 결과는 이것이 전부라는 얼굴을 하고 있다. 오류가 났으면 그 자리에서 알았을 텐데 결과가 나오니 검토 단계까지 그대로 흘러간다.

조치 — 대응 방법

추출이 목적이면 자르지 않는다. 화면 표시와 데이터 추출은 다른 작업이므로 표시용으로 자르는 것은 맞지만 그것을 분석 입력에 그대로 쓰면 안 된다. 고치는 데는 두 가지 방법이 있었는데 LEFT() 를 빼고 content 전문을 가져오는 것과 600자를 넘는 건만 따로 한 번 더 조회하는 것이다. 앞쪽을 골랐다. 이유는 추출은 화면이 아니라 한 번 돌리고 마는 작업이라 결과 크기가 문제되지 않아서다. 대신 결과 파일이 몇 배 커지는 것을 감수했다. 근거는 추출에서 잘린 부분이 나중에 어떤 처리로도 되살아나지 않는다는 점이다.

자를 것이면 길이 분포를 먼저 본다. MAX(LENGTH(content)) 와 한계를 넘는 건수를 알았으면 그 수십 건은 따로 처리했을 것이다. 파서는 처리하는 태그를 나열해 보면 무엇을 안 보는지가 드러나므로 ul·table·blockquote·div 를 확인한다.

빈 결과에는 이유를 붙인다. 0건이 나오면 정말 없는 것인지 못 본 것인지를 가르고 확실히 내용이 있는 대상으로 대조군을 만든다. 다른 곳에 작업을 맡길 때는 긴 목록이나 덤프라고 건너뛰지 말고 끝까지 읽으라는 지시를 명시한다. 안 넣으면 알아서 요약한다.

정리


Share this post on:

Previous Post
근거 네 가지가 같은 것을 가리켰다
Next Post
해결 방법이 셋이라 골라야 했다