-
Notifications
You must be signed in to change notification settings - Fork 53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[조회 성능 개선하기] 현구막(최현구) 미션 제출합니다. #20
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
구막 미션 진행한거 잘 봤어!! 디비 새로 올려서 따라하면서 해봤어! 쿼리 아주 잘짜놨더라구? 대단함!!
코멘트 남겼고 질문들에 대해서도 코멘트 남겨놨어! 붙잡은 시간은 2시간 반인데... 리뷰는 몇 개 안되네... 그냥 개인공부 맛잇게 잘 한 느낌이다 꺼억~ 잘 먹고 갑니다~ 코멘트 확인해주세요 수고했어요
|
||
|
||
인덱싱 후에도 여전히 풀스캔이 발생하나, 실제 데이터 조회는 9개 행만 이루어졌다. | ||
이에 따라 결과 조회 속도가 `0.0031 sec`로 개선되었다. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A번 아주 잘읽었어 구막~! 너무 좋았다~~~~!!
1.
이거는 110039 vishwani의 급여 테이블이야!
CURDATE()
할 필요가 있나 싶어서 스샷 첨부했어!
부서관리나 직급이나 급여나 모두 다 끝나면 종료일자가 표기되고, 아직 하고 있다면 언제까지 지속될지 모르니깐 9999-01-01 로 표기하게 되는데 CURDATE()
를 이용한 BETWEEN 조건절이 필요한가 싶어서 말했봤어. 만약 계약이 되어있고 종료일자가 정해져있기 때문에 CURDATE()
를 써야할 수도 있긴한데! 이것에 대해서 CU한테 미션 초반에 여쭤봤었는데,
라고 오피셜 답변을 주셨다!
- join on 조건절과 WHERE 조건절의 차이에 대해서 확실하게 알고 있는지 궁금! 사실 이 문제와 연관된 문제는 아니긴 하지만 확실하게 알고있는지 질문드립니다!
요것은 내가 말한 데이터 좀 안맞는다는 부분! 테크코스 홈페이지에서는 9월 6일이닷 하하!🥰
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1. CURDATE()
할 필요가 있나
9999
인걸 강의자료에 적어주셨으면 더 좋았을거 같은데!!
풀이 당시에는 9999
의 존재도 몰랐고, 현재 시간을 기준으로 비교하는게 좋을거라 생각해서 저렇게 접근했넹..
9999
인걸 알게 됐으니 한 번 리팩토링 해보겠으!!
2. join on 조건절과 WHERE 조건절의 차이
오... 차이를 전혀 모르고 있었어. 애초에 JOIN
에 ON
말고 WHERE
도 가능하다는 걸 몰랐네...👍 👍
INNER JOIN을 사용할 때는
WHERE
와 차이가 없지만, OUTER JOIN을 사용할 경우 결과가 달라진다!
ON
은JOIN
이 일어나기 전에 조건이 붙어서 해당되지 않는 행에는 정보가 NULL로 표기되지만,
WHERE
는JOIN
을 우선 수행한 후 조건이 붙어서 해당하지 않는 조건 행은 제거된 채로 해당되는 행만 결과로 표시된다!즉, 이 차이를 이용하면 조건에 해당되지 않아도 함께 결과로 나타낼 수 있다.
급하게 찾아서 공부해본바로는 이정도인거 같은데, 올바르게 이해한걸까? 🤔
사원번호/이름/연봉/직급명/지역/입출입구 까지만 확인하고 입출입시간에 대해서는 자세히 안봤는데, 미묘하게 다른게 많네...
데이터가 안 맞는다는게 무슨 말인지 이제야 알겠다 😵
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
inner join에서는 동일한데 outer join 은 좀 다르긴하지! outer join에서의 on 절은 드리븐 테이블을 먼저 조건문 통과시키고 들고오게 되는거니깐!
https://blog.leocat.kr/notes/2017/07/28/sql-join-on-vs-where
여기 예시가 굉장히 잘 나와있어! 플젝 쿼리 짜면서 이것 때문에 데이터가 예상한대로 안나왔던 기억이 있는데 예시를 통해 이번에 알아가면 좋을 것 같어!!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
엇! 파즈 덕분에 공부하면서 읽었던 블로그구만!!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
몰래 보다가 데이터가 안맞는 부분? 답 알거 같아서 남기고 감!
CU자료는 Timezone이 'Asia/Seoul' (UTC+9)로 되어 있어서, 기존 시작보다 9시간씩 더한 값으로 보이는 듯!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오오옷!!
README.md
Outdated
|
||
그러나 PK를 부여한 이후 programmer 테이블 스캔시 row 개수가 71,000개에서 77,000개로 증가했다. | ||
'왜 증가한 것인지?', 'row 개수 증가에 따라 query cost가 증가했음에도 속도는 더 빨라진 이유가 무엇인지?' | ||
는 조사가 더 필요할 것 같다. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이거 나도 궁금해져서 좀 실험을 해봤엉
구막 말대로 rows, cost가 늘어났어!
근데 신기한건 왜 rows와 count 쿼리의 결과값이 다를까?
링크
그 이유는 예측치 일뿐 정확하지 않기 때문이라고 하네!
그러면 왜 저게 늘어날까?? 일단 pk가 없을 떄에는 클러스터 인덱스가 mysql의 내부적인 자체 클러스터 인덱스로 돌아가고(그것은 사용자가 알 수 없음) 그런데 pk를 걸어주면서 클러스터 인덱스가 생성되면서 그 추정치가 변한 것 같어. 그리고 내거는 rows가 74k 인데 이건 아마 나는 auto_increment 값은 안줘서 그런 것 같은데.. 이것도 내부적으로 좀 다르게 돌아가는 것 같다!!
이거는 씨유조 단톡에도 말 나눠봤는데, 여기서도 추정 row가 달라지면서 추정치가 달라졌을 것 같다의 의견이 나왔어!
추가로, cost가 낮아져도 더 느려지는 경우도 있다는 말도 나왔업!(filter를 걸면서 필터 성능을 먹게되면서 느려지는 경우)
아무튼 요거는 그렇게 크게 신경 안써도 될듯~! 말그대로 추정치 일뿐이니깐, 하지만 굉장히 흥미로운 주제다!!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
결국 실행계획에서 rows는
- 추정치일뿐, 완벽하게
count(*)
와 일치하는 값은 아니다. - PK를 걸어주지 않았을 땐 mysql 내부에서 자체적으로 돌리는 클러스터드 인덱스가 존재한다.
- PK를 걸어주면 새로운 클러스터드 인덱스 생성 + 몇 가지 설정 변화로 rows 값이 달라질 수 있다.
겠군!!
또 속도는 cost와 비례하지 않고... 뭔가 다른 것에 영향을 더 받는구나.
와우!! 이정도만 알아도 쿼리 튜닝으로 속도를 개선할 때 헤매는 시간이 확 줄어들듯!!! 👍 👍 💯
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🥰
|
||
### cross join 제거 | ||
인비로부터 ['ON 조건 없이 JOIN을 수행할 경우 CROSS JOIN이 된다'](https://stackoverflow.com/questions/16470942/how-to-use-mysql-join-without-on-condition/16471286) 라는 이야기를 듣고 | ||
CROSS JOIN을 제거하도록 쿼리를 수정해보았다. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍👍👍👍👍👍👍👍👍👍👍👍👍
``` | ||
![image](https://user-images.githubusercontent.com/37354145/137477321-3fe6d945-1916-4cb4-a6e7-1a8ec883befa.png) | ||
|
||
duration에는 드라마틱한 변화가 없었지만, 그래프가 조금 더 간결해졌다! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SELECT 절엔 스칼라 서브쿼리, FROM 절엔 인라인뷰 서브쿼리, 내 머리에 남은건 그냥 서브쿼리... 🤣
FROM | ||
programmer | ||
WHERE | ||
(hobby = 'Yes' AND dev_type LIKE '%Student%') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오 안그래도 처음에 파즈처럼 Student
컬럼으로 접근 했었는데...
covid 테이블의 컬럼 개수가 너무 많아서 컬럼들을 함부러 쓰기 무섭다는 생각 + 요구사항 문구에서 주어진 컬럼 covid.id, hospital.name, user.Hobby, user.DevType, user.YearsCoding
만 사용해야한다고 생각하고 쿼리를 작성했어!!
programmer | ||
WHERE | ||
(hobby = 'Yes' AND dev_type LIKE '%Student%') | ||
OR (years_coding = '0-2 years' AND dev_type LIKE '%Developer%') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이것도 역시 #20 (comment) 때문에.. 🥲
programmer | ||
WHERE | ||
country = 'India' | ||
) AS indian ON programmer_id = indian.id |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
되게 잘짰다!! 커버링 인덱스를 잘 이용했네!!!
나는 단순히 모수테이블을 줄여야 된다는 생각으로 커버링 인덱스를 적용한 모수 테이블을 from 으로 삼았는데 결국엔 covid 때문에 다 꼬이는 느낌이었는데, 여기서는 from을 covid로 삼고 다른 조인을 효율적으로 했네 좋다
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
하하하ㅏ 커버링 인덱스라는 용어를 몰라서 한참 공부했다.. 🥲 꼭 외워야지
커버링 인덱스를 잘 이용하려고 고민한건 아니구!!
성능이 너무 안나오길레 답답해서 하나씩 인덱싱 추가한게 커버링 인덱스를 잘 이용한것처럼 보였나보다..
(너무 좋게 봐준거 아냐? 🤣 )
covid
테이블을 from으로 삼은건 hospital
, member
, programmer
들의 id가 모두 covid
에 있길레
'covid
에서 시작하면 JOIN이 깔끔하게 되겠군!' 라고 생각했어!
``` | ||
|
||
`covid` 테이블 관련 쿼리를 수정한 후 만족스러운 결과를 얻을 수 있었다. | ||
그러나 동일한 쿼리를 이용해서 여러차례 조회를 시도하면 0.033 ~ 0.096 sec 까지 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
편차가 큰 이유는 자체 캐싱을 해서 그렇다고 추측 중이야. 처음 오래 걸리는 쿼리도 다시 호출하면 일단 한 단계 확 빨라지더라구 ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
나도 처음엔 그렇게 생각했는데, 캐싱이 맞나 의심이 되고 있어...
0.096에서 0.033까지 점진적으로 줄어드는 형태라면 '쿼리 자체를 캐싱하겠구나' 라고 생각하겠는데,
0.088 / 0.042 / 0.092 / 0.033 / 0.035 / 0.096 / 0.041
이런식으로 나와 버리니까 원인 추측이 너무 어렵더라구... 😵
미션 요구사항을 제대로 충족한건지도 의심된다 😭
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ㅋㅋㅋㅋㅋ 그래도 이 정도면 괜찮은 것 같은데!! 나도 궁금하다 이 부분... 왜 같은 쿼리인데 응답시간이 계속해서 변하는 거쥐................................. 이 부분은 진쫘 몰겄네... 한 번 물어봐야겠당! 아니면 캐시의 전략일까? 몇 번 쿼리 치고나면 캐시 삭제해라! 라든지! 한 번 씨유한테 물어볼게!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오!! 씨유한테 여쭤볼 생각을 못했네!!
@Hyeon9mak 추가로 단 코멘트 링크만 한 번 확인해보세요! 확인했다고 말해주면 그때 어프로브 누를게~! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
구막~ 수고했어~!!!!!!!!!~!~~! 남은 레벨도 화이팅 미션도 화이팅!!!!!!!!!!
책에서는 컬럼의 변화가 없다고 가정하고 이야기한 것 같다. | ||
|
||
### EXPLAIN ANALYZE | ||
MySQL 8.0.18 버전부터는 쿼리의 실행 계획과 단계별 소요된 시간 정보를 확인할 수 있는 `EXPLAIN ANALYZE` 기능이 추가됐다. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오우 이런게 있구나!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
그림의 떡 🥲
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ㅋㅋㅋㅋㅋㅋ
때문에 단순히 AUTO-INCREMENT 한 정수 값을 담는 PK보다는 의미가 담긴 컬럼이 좋다. | ||
|
||
> 그러나 대부분의 현업 서비스에서 컬럼은 언제 어떻게 변화할지 확신할 수 없다. | ||
그래서 의미가 담긴 컬럼을 PK로 사용하기보다, AUTO-INCREMENT한 정수 값을 PK로 사용한다고 알고 있다. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
맞어 나도 이렇게 알고있어! 전에 김영한님 강의 들으면서 예시를 들어줬었던게, 주민번호를 pk로 삼고있다가 국가에서 주민번호 같은 개인정보 들고있지 말라고 지침 내려와서 그때 pk 변경작업 때문에 고생했다는 썰을 들은적이 있다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
카카오가 그랬던가?! 나도 얼핏 이야기 들은 기억이 난다!!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
어딘지는 잘 모르겠는데 암튼 그랫다뉑! auto_increment가 속편하긴 한듯!!
이요오오오오옵!!! 파즈!!!!
부지런히 미션 진행했어야했는데, 제출 마감일이 되어서야 제출하넹 🥲 ..
쿼리랑도 그렇게 친하지 않은데, 쿼리 최적화까지 처음 접하니까 정말정말 어렵고 따분하게 느껴지다가,
어느정도 감이 잡히니까 흥미가 생겨서 B-2 풀때 쯤부터는 재밌게 진행했음! 😃
재미없게 결과만 딱딱 적어놓는 것보다, 풀이한 과정을 일기처럼 적는게 좋을거 같아서 시도해봤어!!!
여기서 읽으면 된다!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
그리구 미션 진행하면서 질문거리도 생겼어.. 😭
1. Query cost와 Duration은 비례하지 않는다?
B-1 미션을 진행하면서 성능 개선을 위해
programmer
테이블의id
를 Primary Key로 변환하고 나니까조회되는 행의 개수가 71,000개에서 77,000개로 증가했어!?!?!
행의 개수와 비례해서 Query cost 또한 증가했고!!
그런데 Duration은 오히려 작아졌단 말이지?!
이런 일이 벌어진 이유가 무엇일까?!
파즈와 함께 알아보기 위해 아껴뒀어!! 하하하하하 💥 🥊
2. Duration 편차가 지나치게 크다.
다른 미션에서는 이런 문제가 없었는데, B-4 미션에서는 유독 Duration간 편차가 굉장히 크게 나왔어.
최소 0.033 sec 에서 최대 0.096 sec 까지 나오는데... 빠르게 연타했다던가 그런적도 없고,
Duration이 점차 빨라지거나 느려지는게 아닌, 정말 들쑥날쑥 랜덤하게 변화해서 이유를 잘 모르겠어...
이것도 파즈와 함께 알아보기 위해 아껴뒀어!! 하하하하하하하하 💥💥💥 🥊 🥊 🥊
그럼!! 리뷰 잘부탁해!!
우주최강 긍정기린 🦒 🦒 🦒 🦒 파즈 화이팅!!!