Skip to content

[조회 성능 개선하기] 춘식(안예장) 미션 제출합니다.#34

Merged
Gomding merged 2 commits intowoowacourse:rinsabbitfrom
bimppap:step1
Oct 25, 2021
Merged

[조회 성능 개선하기] 춘식(안예장) 미션 제출합니다.#34
Gomding merged 2 commits intowoowacourse:rinsabbitfrom
bimppap:step1

Conversation

@bimppap
Copy link
Copy Markdown

@bimppap bimppap commented Oct 17, 2021

반가워요 찰리!! 제출이 좀 늦었네요ㅠㅠ
쿼리 튜닝은 처음 해봐서 이렇게 하는 게 맞는 지 모르겠네요ㅎㅎ
그래도 실행시간 단축시키는 맛으로 즐겁게 미션 풀었던 거 같아요.
제 컴퓨터에서는 리드미 작성이 버벅거려서 노션에 따로 정리해봤어요!!
문제 풀이는 여기서 확인할 수 있습니다><
개인적으로 궁금했던 점이 여러 개 있었는데 지금 생각나는 게 하나 밖에 없어서!! 리팩토링하면서 생각나면 디엠으로 물어볼게요 😉

Q) 걸어둔 인덱스가 어떤 쿼리에선 성능을 향샹시키는데 어떤 쿼리에선 성능을 저하시킬 땐 어떻게 개선하는 게 좋을까요? B2와 B3에선 유용하게 쓰인 인덱스가 B4와 B5에선 성능을 저하시켜서요 🥲

Copy link
Copy Markdown

@Gomding Gomding left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

안녕하세요 춘식!
리뷰가 늦어져서 죄송합니다 🙇 🙇 🙇

미션 너무 깔끔하게 구현해주셨네요 😮
리뷰하면서 많이 배워갑니다!!

몇가지 코멘트 남겼으니 확인 부탁드려요!!

Comment thread README.md
### * 요구사항

- [ ] 주어진 데이터셋을 활용하여 아래 조회 결과를 100ms 이하로 반환
- [X] 주어진 데이터셋을 활용하여 아래 조회 결과를 100ms 이하로 반환
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A.쿼리 연습
image

이미 요구사항도 넉넉하게 충족했지만 조금 더 개선을 해보면

create index `I_사원번호_입출입구분_입출입시간_지역` ON tuning.사원출입기록 (사원번호, 입출입구분, 입출입시간, 지역);	

이런식으로 인덱스를 걸면 커버링 인덱스가 돼서 디스크 I/O가 일어나지 않고 인덱스만으로 데이터를 가져올 수 있어요!
근데 실무에서는 이렇게 할 수 있을지 모르겠어서..

조금 차선책으로 아래의 복합 인덱스 정도만 걸어주는게 어떨까 생각합니다 😢
사원 번호가 cardinality가 높으니 사원번호 -> 입출입구분 순서로 하는 복합인덱스 입니다!

create index `I_사원번호_입출입구분` ON tuning.사원출입기록 (사원번호, 입출입구분);	

Comment thread README.md

- [ ] 주어진 데이터셋을 활용하여 아래 조회 결과를 100ms 이하로 반환
- [X] 주어진 데이터셋을 활용하여 아래 조회 결과를 100ms 이하로 반환

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

항상 인덱스를 초기화 하고 하셨군요 👍
저도 이렇게 했어야했는데..

Comment thread README.md
- [X] 주어진 데이터셋을 활용하여 아래 조회 결과를 100ms 이하로 반환

- [ ] [Coding as a Hobby](https://insights.stackoverflow.com/survey/2018#developer-profile-_-coding-as-a-hobby) 와 같은 결과를 반환하세요.
- [X] [Coding as a Hobby](https://insights.stackoverflow.com/survey/2018#developer-profile-_-coding-as-a-hobby) 와 같은 결과를 반환하세요.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

제 조회 쿼리가 부끄러울 정도로 잘짜주셨네요 😮
인덱스까지 깔끔하게 잡아주셨어요! 많이 배워갑니다 👍 👍 👍

Comment thread README.md
- [X] [Coding as a Hobby](https://insights.stackoverflow.com/survey/2018#developer-profile-_-coding-as-a-hobby) 와 같은 결과를 반환하세요.

- [ ] 각 프로그래머별로 해당하는 병원 이름을 반환하세요. (covid.id, hospital.name)
- [X] 각 프로그래머별로 해당하는 병원 이름을 반환하세요. (covid.id, hospital.name)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

여기는 저도 혼란스러웠던 부분인데
programmer_id 는 이미 covid 테이블에 있으니 programmer 테이블을 조인할 필요가 없더라구요 🤔

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

추가로 해당 문제에서 ORDER BY 사용은 취향 차이라고 생각하지만
저는 temp 테이블이랑 file sort가 발생할 수 있어서 필요한 경우에만 써야겠다 생각했어요!

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

programmer_id 는 이미 covid 테이블에 있으니 programmer 테이블을 조인할 필요가 없더라구요

covid 테이블에는 존재하나 programmer 테이블에는 존재하지 않는 id,
혹은 그 반대의 경우가 있을 경우를 염려하여 programmer 테이블도 covid 테이블과 inner join을 했습니다! :3

지금 보니 order by 없이도 동일한 결과가 나오네요ㅎㅎ 사라져라 오더바이

Comment thread README.md
- [X] 각 프로그래머별로 해당하는 병원 이름을 반환하세요. (covid.id, hospital.name)

- [ ] 프로그래밍이 취미인 학생 혹은 주니어(0-2년)들이 다닌 병원 이름을 반환하고 user.id 기준으로 정렬하세요. (covid.id, hospital.name, user.Hobby, user.DevType, user.YearsCoding)
- [X] 프로그래밍이 취미인 학생 혹은 주니어(0-2년)들이 다닌 병원 이름을 반환하고 user.id 기준으로 정렬하세요. (covid.id, hospital.name, user.Hobby, user.DevType, user.YearsCoding)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

동료를 찾아서 매우 기쁩니다 😄
해당 문제에서 조건이 프로그램이 취미인 학생 or 주니어(0-2년) 이라고 저도 피드백 받았습니다 ㅎ_ㅎ

저도 프로그램이 취미 and (학생 or 주니어) 라고 생각했어서.. 😭

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

추가로 covid 테이블을 조인할 때 아래와같이 하면 가져오는 row를 더 줄여볼 수 있답니다 :)

INNER JOIN (SELECT id, hospital_id, programmer_id FROM covid WHERE programmer_id > 0) AS covid ON programmer.id = covid.programmer_id

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where 절의 or 조건에서는 인덱스가 어떻게 되는지도 찾아보시면 도움이 될거에요!

Copy link
Copy Markdown
Author

@bimppap bimppap Oct 23, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

추가로 covid 테이블을 조인할 때 아래와같이 하면 가져오는 row를 더 줄여볼 수 있답니다 :)

아래 쿼리로 수정해보았는데 가져오는 row 수가 똑같았어요... 🥲
실행계획에서 ref가 subway.hospital.id (PK) 에서 func로 바뀌긴 했는데 차이가 있을까요???

제가 쿼리를 잘못 읽었었네요ㅋㅋㅋㅋ

Copy link
Copy Markdown
Author

@bimppap bimppap Oct 24, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where 절의 or 조건에서는 인덱스가 어떻게 되는지도 찾아보시면 도움이 될거에요!

오 OR 조건에서는 인덱스를 타지 않는군요 😮
이 쿼리에서는 OR 조건에 인덱싱된 칼럼이 없어서 문제가 없어보이는데 맞을까요?ㅎㅎ
찾아보니 인덱스를 안 타는 경우가 더 있었어요!!

Comment thread README.md
- [X] 프로그래밍이 취미인 학생 혹은 주니어(0-2년)들이 다닌 병원 이름을 반환하고 user.id 기준으로 정렬하세요. (covid.id, hospital.name, user.Hobby, user.DevType, user.YearsCoding)

- [ ] 서울대병원에 다닌 20대 India 환자들을 병원에 머문 기간별로 집계하세요. (covid.Stay)
- [X] 서울대병원에 다닌 20대 India 환자들을 병원에 머문 기간별로 집계하세요. (covid.Stay)
Copy link
Copy Markdown

@Gomding Gomding Oct 20, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

저도 계속 개발자에 감정 이입해서 하다보니 뒤늦게 알아차린 사실인데
이 문제는 개발자에 대한 집계가 아니라서 programmer 테이블을 사용하지 않아도 괜찮더라구요..
제가 잘못해서 country 조건을 빼먹었군요..

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hospital에서 가져와야할 정보는 서울대병원 row 1개라서
INNER JOIN + 서브쿼리로 가져올 row 수를 줄여보는건 어떨까요? 😄

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BETWEEN 같이 범위 검색에는 함정이 있습니다. 물론 지금은 문제가 없어 보입니다! 😄

image

출처 : 인덱스 정리 및 팁 - 이동욱 개발자님

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

처음엔 where 절에서 prgrammer.country에 조건을 걸었으니 covid.programmer_id에 인덱스를 걸었으나 오히려 속도가 더 느려졌다. 이게 질문 주신 내용인것 같은데 당장 떠오르는게 없네요.. 뭔가 발견하면 DM으로 알려드리겠습니다!!

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

현재 file sort 가 일어나는데 group by를 사용하면 file sort 가 일어나는데
이것을 order by null 을 사용하면 file sort 를 없앨 수 있습니다.
order by null은 표준이 아니라 mysql에서만 지원해주는 기능입니다 :)
GROUP BY의 Filesort 작업 제거

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 order by null 신기하네요 좋은 정보 감사합니다!!!!

Copy link
Copy Markdown
Author

@bimppap bimppap Oct 23, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

앗 그런데 order by null 로 하니 정렬이 되지 않네요. 정렬이 필요없을 때 사용하면 좋을 것 같습니다!!!!
스크린샷 2021-10-24 오전 2 06 25

@bimppap
Copy link
Copy Markdown
Author

bimppap commented Oct 24, 2021

반가워요 찰리!! 뒤늦게나마 리드미에 쿼리를 추가했습니다... 🥲
피드백 반영해서 쿼리도 수정했습니다!!
쿼리를 변경하면서 몇몇은 인덱스 변경도 시도해보았는데 별 차이 없거나 느려지더라고요ㅋㅋㅋ

추가 피드백은 언제나 환영이랍니다 이번에도 잘 부탁드립니다!!!

Copy link
Copy Markdown

@Gomding Gomding left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

춘식 미션 진행한거 보면서 많이 배웠습니다!

특히 최소한의 인덱스로 기능을 향상시키는 점이 인상적이었어요 👍

이미 깔끔하게 인덱스를 추가해주셔서
몇가지 의견을 남기고 Approve 할게요 :)

Comment thread README.md
```sql
-- 1차 수정 : 서브쿼리 생성. 서브쿼리 내에서 where 조건절 사용
-- 실행계획과 성능엔 차이가 없었다.
-- 서브쿼리로 수정하면서 hospital.id 대신 programmer.country 에 인덱싱을 걸어보았으나 성능은 더 느려졌다.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요건 제가 현구막 PR에 파즈가 남긴 코멘트를 보면서 깨달은 용어를 공유합니다!

image

Comment thread README.md
WHERE
(programmer.hobby = 'yes'
AND programmer.dev_type = 'student')
OR programmer.years_coding = '0-2 years'
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요 컬럼이 주니어(0~2년차)인데 years_coding_prof 라는 컬럼이 또 따로 있더라구요!
프로로서의 년차를 의미하는것 같아요 :)

이걸 활용하면 dev_type이 'student' 이면서 years_coding이 '0-2 years' 인 애들을 걸러줄 수 있겠네요!

Comment thread README.md
Comment on lines +185 to +187
-- 0차(수정X)
CREATE INDEX idx_covid_hospital ON covid (hospital_id);
CREATE INDEX idx_member_age ON member (age);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

리뷰하면서 느끼지만 최소한의 인덱스로 성능 개선을 잘 해주셨네요 👍 👍 👍 👍 👍 👍 💯

Comment thread README.md

```

### B - 4
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

programmer_id 에 인덱스를 걸었을 때 성능이 저하되는 이유는 테이블 내 특정 데이터 중복이 비정상적으로 높다랑 연관된다고 생각했어요!

image

@Gomding Gomding merged commit 4f880cd into woowacourse:rinsabbit Oct 25, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants