궁금한게 key_length 를 이용해서 어떻게 사용하는지에 대해서가 22강에서 안나왔는데 그 이후로 나오나요? key_len 이 기대한것보다 적으면 인덱스가 잘 사용되고 있지 않다고만 설명을 하고 지나가셨는데 이후에 key_len 값을가지고 개선 하는방법이 나오는지 알고싶습니다.
SELECT m.member_id, m.member_name, m.grade, COUNT(o.order_id) AS order_count, SUM(o.total_price) AS total_spent FROM member m JOIN orders o ON m.member_id = o.member_id WHERE m.grade = 'VIP' GROUP BY m.member_id, m.member_name, m.grade ORDER BY total_spent DESC LIMIT 20; 안녕하세요! 해당 쿼리에서는 group by 순서가 member_id, member_name, grade 순으로 되어있습니다. 강의에서는 group by 는 그룹핑을 할때 (member_id, member_name, grade) 을 기준으로 그룹핑 하여 순서가 상관없지만 인덱스 순서를 GROUP BY 순서에 맞게 인덱스를 설계 해야한다고 하셨습니다. grade 는 where 절에서 vip 상수로 필터링 하므로 인덱스에서 가장 왼쪽(앞)에 와야하지만 왜 member_id, member_name 순서에 맞게 인덱스를 줘야하는지 잘 모르겠습니다. 실제로 (grade, member_name, member_id) 순서로 member 테이블에 인덱스를 주고 EXPLAIN ANALZYZE 를 해보니 Aggregate using temporary table (actual time=373..373 rows=59999 loops=1) 가 나오는것을 확인했습니다. 임시테이블을 만들지 말지의 기준은 GROUP BY 로 그룹핑 하는 대상들이 연속적으로 올 경우는 굳이 임시테이블을 만들 필요가 없다는것으로 이해를 했습니다.(순서대로 오니까 미리 저장할 필요가 없으므로) 하지만 인덱스를 (grade, member_name, member_id) 순서로 줄 경우도 결국 인덱스 Grouping 순서에 맞게 오니까 임시테이블을 만들 필요가 없으니까 using temporary table 역시 발생하지 않아야 하는거 아닌가요? 그리고 설령 (grade, member_name, member_id) 로 주지 않고 (grade, member_name) 로 member테이블에 인덱스를 걸더라도 되는거 아닌가요? 어차피 세컨더리 인덱스 리프노드에는 member_id (pk) 가 선행컬럼을 기준으로 정렬되어 존재하니깐용 감사합니다!
DB 쿼리를 설계하면서 항상 궁금했던 점이 있습니다. 쿼리가 점점 복잡해지다 보면 Sort , GROUP BY 등의 연산을 DB에서 처리하는 것보다, 데이터를 애플리케이션으로 가져온 후 애플리케이션에서 처리하는 것이 더 효율적이지 않을까 하는 생각이 들 때가 있습니다. 그렇다면 일반적으로 DB 쿼리를 최적화할 때는 애플리케이션으로 데이터를 가져와 처리하기보다는, 적절한 Index 설계를 통해 가능한 한 DB에서 연산을 처리하는 것이 맞는 방향일까요? 아니면 상황에 따라서는 필요한 데이터를 DB에서 조회한 후, 일부 연산을 애플리케이션에서 처리하는 것도 하나의 최적화 방법이 될 수 있을까요? 제가 생각하는 방향 자체가 잘못된 것인지, 아니면 실제로 상황에 따라 고려할 수 있는 방법인지 궁금해서 질문드립니다.
안녕하세요 영한님! 강의에서 말씀해 주신 것처럼, 인덱스를 생성한다고 해서 항상 옵티마이저가 해당 인덱스를 사용하는 것은 아니라는 점은 이해했습니다. 그렇다면 실무에서는 특정 인덱스를 어떤 쿼리나 사용 패턴을 고려해서 만들었는지, 그리고 어떤 의도로 설계했는지를 별도로 기록하거나 관리하는 방법이 있을까요? 예를 들어 시간이 지나 다른 개발자가 인덱스를 보더라도, “이 인덱스는 특정 조회 쿼리의 성능을 개선하기 위해 만들었다”와 같은 설계 의도를 파악할 수 있도록 관리하는지가 궁금합니다. 설계 1편에서 소개해 주신 용어 사전처럼 별도의 문서나 규칙을 두고 관리하는 방법이 있는지, 혹은 실무에서 일반적으로 사용하는 다른 방법이 있는지도 궁금합니다!
안녕하세요 영한님, 영한님의 강의로 열심히 학습중인 학생입니다! 실전 진단 - 해결 방안2에서 복합인덱스 관련해 궁금증이 있습니다. 영한님의 강의에서는 (category_id, product_status, created_at)을 복합인덱스로 설정하셨는데, (category_id, created_at)을 복합인덱스로 설정하는 것에 대해서는 어떻게 생각하시는지 궁금합니다. product_status = 'ACTIVE'의 비율이 전체 테이블에 비교했을 때 전체의 85%였고, 이 price 조건을 비교하기 위해 클러스터드 인덱스가 접근해 행 전체를 읽은 후 실행엔진에서 걸러야하는데, product_stauts = 'ACTIVE' 비율이 85%에 해당되기 때문에 높은 확률로 통과하다 보니 인덱스 효용이 떨어질 것 같다는 생각이 들었습니다. 그래서 해당 쿼리를 생각했을 때 product_status도 복합인덱스에 추가할만한 가치가 있을까? 라는 질문을 던졌을 때 (영한님이 말씀해주신 것 처럼, 인덱스도 결국 비용이니깐) 크게 와닿지 못 했는데, 이와 관련해서 영한님의 의견이 궁금합니다! (두 복합 인덱스의 실행 계획) -- (category_id, created_at) -> Limit: 20 row(s) (cost=75331 rows=20)(actual time=0.719..11.5 rows=20 loops=1) -> Filter: ((product.price between 10000 and 50000) and (product.product_status = 'ACTIVE')) (cost=75331 rows=4595) (actual time=0.718..11.5 rows=20 loops=1) -> Index lookup on product using idx_category_created_at (category_id=11) (cost=75331 rows=413612) (actual time=0.698..11.4 rows=48 loops=1) -- (category_id, product_status, created_at) -> Limit: 20 row(s) (cost=78697 rows=20)(actual time=0.6..9.07 rows=20 loops=1) -> Filter: (product.price between 10000 and 50000) (cost=78697 rows=38255) (actual time=0.593..9.06 rows=20 loops=1) -> Index lookup on product using idx_category_status_created_at (category_id=11, product_status='ACTIVE') (cost=78697 rows=344330) (actual time=0.581..9.03 rows=40 loops=1)
안녕하세요~ 강의 수강중 통계정보 갱신에 대해 여쭤보고싶은게 있습니다. 운영중에 간혹가다 옵티마이저가 실행계획을 잘못 선택해서 쿼리를 실행해서 슬로우 쿼리가 발생되는 경우가 종종있었습니다. 이때 use index 를 사용해서 주로 해결했었는데 이번 강의에서는 문제가 되는 테이블의 통계정보를 갱신하면 이런 문제들이 해결된다고 하시던데 운영중인 db 에 통계정보 갱신을 했을때 트레이드 오프같은게 없을까요? 실무에서 보통 어떻게 하셨는지 궁금하네요.
안녕하세요! PK 설계와 관련하여 궁금한 점이 있어 질문드립니다. 강의에서는 AUTO_INCREMENT 를 사용하면 PK가 순차적으로 증가하기 때문에 랜덤한 위치에 데이터가 삽입되는 것을 줄이고, 페이지 분할을 최소화할 수 있어 사용을 권장한다고 이해했습니다. 그런데 한편으로는 MSA 환경에서 PK로 UUID를 많이 사용한다는 이야기를 들었습니다. UUID를 사용하면 각 서비스에서 ID를 독립적으로 생성할 수 있다는 장점이 있다고 하는데, 서비스별로 데이터베이스와 테이블이 분리되어 있다면 각 테이블의 PK는 해당 테이블 내에서만 유일하면 되기 때문에 AUTO_INCREMENT 를 사용해도 문제가 없지 않을까 생각했습니다. 그래서 다음 내용이 궁금합니다. 실제 MSA 환경에서는 일반적으로 PK로 UUID를 많이 사용하는지 UUID 사용으로 인한 인덱스 크기 증가와 페이지 분할 등의 단점보다 UUID의 장점이 더 커지는 판단 기준은 무엇인지 찾아보니까 시간 순서 특성이 있는 UUID v7 라는 것도 있는데 이를 사용하는 건지 이런 궁금증이 생기는데 시원하게 해결이 되지 않아서 질문으로 남깁니다. 항상 좋은 강의 올려주셔서 감사합니다. 다음 강의에 해당 내용에 대한 설명이 다 있는 것을 확인하였습니다. 감사합니다!
커버링 인덱스가 아니라고 가정한다면 클러스터링 인덱스까지 2번의 B+Tree 탐색을 하지만 커버링 인덱스라면 이런 탐색을 한번 줄여 발생하는 IO 작업을 최적화 하는것으로 이해 했습니다 커버링 인덱스 말고도, 자주 사용되는 페이지의 위치를 자동으로 InnoDB에서 어댑티브 해시 인덱스라는 공간에 저장 하는것으로 알고 있는데 이 방식도 IO 작업을 최적화 하는 것인지 궁금 합니다
안녕하세요 영한님! 강의 재밌게 잘 듣고있습니다. 아직 섹션3까지 들었는데 MySQL 아키텍처 설명을 너무 잘해주셔서 너무 재밌게 들었습니다! 개인적으로 실무에서 PostgreSQL을 사용하고 있는데 혹시 PostgreSQL 아키텍처 강의도 업데이트 예정이 있으신지 궁금합니다!