Skip to content
isdnetworks
Go back

두 가지를 한 번에 바꿨다

목록이 느려서 두 가지를 고쳤다. 인덱스를 넣고 조회 방식도 바꿨다. 빨라졌는데 어느 것 때문인지는 모른다.

Table of contents

Open Table of contents

왜 알아야 하는가

당장은 빨라졌으니 문제가 없어 보였다. 다만 몇 가지가 걸렸다.

다음에 비슷한 상황에서 무엇을 먼저 할지 모른다는 것이 첫째다. 둘 다 하면 되지만 그러면 시간이 두 배로 든다.

둘째로 하나가 불필요할 수 있는데 인덱스 하나를 더 두는 것은 INSERTUPDATE 를 그만큼 느리게 만든다. 효과가 없는데 남아 있으면 비용만 내고 있는 것이다.

셋째로 되돌릴 때 무엇을 되돌릴지도 모르는데 둘 다 빼면 다시 느려지고 하나만 빼려면 어느 것인지 골라야 한다. 판단할 근거가 없는 상태가 됐다.

검증 — 원래대로 두고 하나씩 쟀다

되돌리고 하나씩 적용했다.

원래                    4.2초
인덱스만 추가            3.8초
조회 방식만 변경          0.9초
둘 다                   0.7초

조회 방식이 대부분을 줄였고 인덱스가 줄인 것은 0.4초뿐이었다. EXPLAINrows 도 같은 방향으로 움직여서 숫자와 실행 계획이 맞았다.

인덱스는 빼도 될 정도였는데 자료가 늘면 효과가 커질 것이라 남겼다. 알고 두는 것과 모르고 두는 것은 다르고 이제 판단 근거가 생겼다.

재는 방법을 정했다

매번 손으로 재면 조건이 달라진다.

$t = microtime(true);
$rows = $this->model->get_list($cond);
$elapsed = microtime(true) - $t;
log_message('debug', sprintf("get_list %.3f초 %d건", $elapsed, count($rows)));

microtime 으로 재고 건수도 같이 남겼다. 같은 조건으로 세 번 돌려 평균을 봤다.

1회차  1.24초
2회차  0.71초
3회차  0.69초

첫 회차를 빼고 본 이유가 있다. InnoDB 는 필요한 페이지를 버퍼 풀에 올려 놓고 쓰는데 첫 실행은 그것을 디스크에서 읽어 온다. 두 번째부터는 이미 올라와 있으니 같은 쿼리라도 다른 것을 재게 된다.

반대 방향의 함정도 있었다. 쿼리 캐시가 켜져 있으면 두 번째 실행이 결과를 그대로 돌려받아 부당하게 빨라진다. SELECT SQL_NO_CACHE 를 붙여 그것을 끄고 쟀다.

실제 사용에서는 캐시가 있는 상태가 대부분이라 둘 다 기록했다.

자료 상태도 맞춰야 했다. 측정 사이에 자료가 늘면 비교가 안 된다.

CREATE TABLE product_snapshot AS SELECT * FROM product;

측정 전에 원래대로 되돌린다.

TRUNCATE product;
INSERT INTO product SELECT * FROM product_snapshot;

product_snapshot 으로 같은 시점을 고정하고 배치가 안 도는 시간도 골랐다. 조건이 같아야 비교가 된다.

무엇을 바꿨는지 남겼다

측정과 함께 무엇을 바꿨는지 적었다.

2014-10-06 상품 목록 성능

  원래                              4.2초 / 4.5초 (캐시 없음)
  + idx_category_status 인덱스       3.8초 / 3.9초
  + 조회를 조인으로 변경              0.9초 / 1.1초
  둘 다                             0.7초 / 0.9초

  결론: 조회 방식이 주요 원인. 인덱스는 보조.
        자료 증가 시 인덱스 효과가 커질 것으로 보여 유지.

숫자만 남기면 몇 주 뒤에 그 숫자가 무엇의 결과인지 모른다. 행 수와 SQL_NO_CACHE 여부와 변경 내용을 함께 적었다.

다만 한 번에 하나씩 바꾸는 것이 항상 옳지는 않았다. 급할 때는 둘 다 바꾸는 것이 맞고 서비스가 멈춰 있으면 원인 분석보다 복구가 먼저다.

급할 때      전부 적용 → 복구 → 나중에 나눠서 측정
여유 있을 때  하나씩 적용하며 측정

복구와 원인 규명을 나눈 것인데 둘을 같이 하려니 둘 다 늦어졌기 때문이다.

정리


Share this post on:

Previous Post
설정을 저장소 밖으로 뺐다
Next Post
같은 파일인데 한쪽에서만 404였다