안녕하세요. 강의 잘 보고 있습니다! [실습] WHERE문이 사용된 SQL문 튜닝하기 - 2 해당 강의에서 질문이 있습니다 :) 이전 강의에서 멀티 컬럼 인덱스의 경우, 첫번째 컬럼 기준으로 먼저 정렬하고, 그 다음 두번째 컬럼 기준으로 정렬한다고 배웠던 것 같습니다! 따라서 idx_created_at <-> idx_created_at_department 실행계획 idx_department <-> idx_department_created_at 실행계획이 각각 비슷할 것이라고 예상했는데, 강의에서는 idx_created_at과 두 개의 멀티 컬럼 인덱스 idx_created_at_department, idx_department_created_at 가 비슷하다는 것을 알 수 있었습니다! 이유가 궁금하여 질문 남겨봅니다 !
강사님 안녕하세요! 강의 잘 듣고 있습니다. 너무 좋네요! 😊 [실습] 인덱스 직접 설정해보기/성능 측정해보기 => 실습 중 질문이 있습니다! user.age에 인덱스 생성 전 [2026-07-12 11:51:16] 1,028 rows retrieved starting from 1 in 420 ms (execution: 110 ms, fetching: 310 ms) => 이런식으로 평균 400ms 속도가 측정되다가 user.age에 인덱스 생성 후 [2026-07-12 12:19:48] 1,028 rows retrieved starting from 1 in 510 ms (execution: 11 ms, fetching: 499 ms) [2026-07-12 12:19:59] 1,028 rows retrieved starting from 1 in 339 ms (execution: 9 ms, fetching: 330 ms) [2026-07-12 12:20:09] 1,028 rows retrieved starting from 1 in 329 ms (execution: 7 ms, fetching: 322 ms) 인덱스 생성 후 최초 실행시에 510ms로 시간이 한번 튀는데 검색해 봤을때는 인덱스 생성 직후 캐싱 되어있지 않아서 발생하는 현상이라고 하는데 이러한 것은 신경쓰지 않아도 되는지 궁금합니다! 감사합니다!
안녕하세요 강사님. [실행 계획에서 type 의미 분석하기 (const, range, ref)] 강의에서 " Index Range Scan할 때 조회 범위가 크면 성능 저하의 원인이 되기도 한다. "라는 내용을 듣고 정말인지 궁금해져서 EXPLAIN을 한번 돌려봤습니다. CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100), age INT ); -- 높은 재귀(반복) 횟수를 허용하도록 설정 -- (아래에서 생성할 더미 데이터의 개수와 맞춰서 작성하면 된다.) SET SESSION cte_max_recursion_depth = 1000000; -- 더미 데이터 삽입 쿼리 INSERT INTO users (name, age) WITH RECURSIVE cte (n) AS ( SELECT 1 UNION ALL SELECT n + 1 FROM cte WHERE n < 1000000 -- 생성하고 싶은 더미 데이터의 개수 ) SELECT CONCAT('User', LPAD(n, 7, '0')), -- 'User' 다음에 7자리 숫자로 구성된 이름 생성 FLOOR(1 + RAND() * 1000) AS age -- 1부터 1000 사이의 난수로 나이 생성 FROM cte; CREATE INDEX idx_age ON users (age); EXPLAIN SELECT id FROM users WHERE id BETWEEN 1 AND 100000; -- type : range 결과 창에서 rows 가 100,000이 아니라 110,836으로 나오더라고요. 옵티마이저가 id 는 PK이라서 중복이 없을 거라는 것을 알고 Auto Increment가 적용되어 있어서 순차적으로 데이터가 들어갔음도 알텐데 왜 10만 개로 딱 떨어지게 예측하지 못하는지 직관적으로 잘 이해가 가지 않습니다. 감사합니다.
최근에 Redis 의 개발사가 라이선스 정책을 변경하면서, 더 이상 완전한 무료 오픈소스로 부르기 애매해지는 사건이 있었습니다. 이에 반발한 AWS, 구글 등 빅테크 기업들이 모인 Linux Foundation 에서 기존 Redis 코드를 그대로 복사해서(포크해서) 만든 진짜 100% 무료 오픈소스가 바로 Valkey 입니다. 라고 제미나이가 그러던데... 요즘은 Valkey를 선택하는 게 대세인가요?
안녕하세요. 좋은 강의 감사합니다. 강의와 직접적으로 관련 있는 내용은 아니지만 궁금한 점이 있어 질문드립니다. 클라이언트에서 MySQL 서버로 아래와 같이 요청할 텐데 BEGIN 쿼리 COMMIT 3번에서 MySQL 서버가 클라이언트의 Commit 요청을 받고 처리 완료 후, 클라이언트에게 응답하려는 순간 네트워크가 단절되면 Commit은 되었지만 클라이언트는 실패로 인지할 텐데 이런 경우 어떻게 대응해야 하는지 궁금합니다. 아니면 MySQL 서버에 네트워크 전송 실패를 감지하고 해당 트랜잭션을 보정하는 동작이 있을까요? 감사합니다.
안녕하세요 항상 강의 잘 수강하고 있습니다 ! 강의를 수강하다 질문이 생겨 여쭤보게 되었습니다. 강의 진행 시에는 Service 계층에서 Redis 설정을 적용시켰는데, Redis 설정은 Service 계층에서 적용하는 것이 일반적일까요 ? Repository나 Controller 계층에서도 걸어줘도 차이가 있는지 궁금해서 여쭤봅니다 !
상단의 스크린샷이 저의 로컬에서 확인된 거구요 아래는 선생님의 결과 입니다 [실습] 유저 이름이름 특정기간에 작성된 글 검색하는 SQL문 튜닝하기 3:30초 구간 입니다 똑같이 했는데 왜 TYPE과 KEY 변경되어 있을까요? 제가 잘못하고 있는건가요? 따라 쓴거도 아니고 NOTION에 있는걸 복붙 했습니다 ;;;
안녕하세요. redis 강의를 통해 간단한 프로젝트로 적용을 하려고 합니다. @Cacheable( value = "reviewList", key = "'review:store:' + #storeId + ':page:' + #pageable.pageNumber", cacheManager = "reviewCacheManager", condition = "#pageable.pageNumber == 0") @Transactional(readOnly = true) public Page<ResViewReviewDto> getReviews(UUID storeId, ReviewRepositorySearchConditionDto condition, Pageable pageable) { Page<ResViewReviewDto> reviews = reviewRepository.findReviews(storeId, condition, pageable); return new PageImpl<>(reviews.getContent(), pageable, reviews.getTotalElements()); } 원래는 return reviews를 했더니 계속 조회를 누르면 ClassCastException: LinkedHashMap cannot be cast to Page 이 오류가 나오게 됩니다. 강의에서는 그냥 getContent를 List로 반환값을 보냈는데 혹시 위 코드처럼 new PageImpl 형식으로 return 해도 괜찮을까요?
애플리케이션단에서 범위조건 사용할때 2024-01-02 00:00:00 값을 어떻게 넘겨야줘야되나요? 말씀하신 내용 토대로 보면 라스트 finished_at : 2024-01-01 00:00:02 id : 8 두가지정도만 넘길수 있을꺼 같은데요 그래서 애플리케이션 파라미터는 두가지값남 넘기고 처리 해야되지 않나 싶어서 여쭤봅니다. 그래서 해당쿼리로 날려도 상관 없을지 질문드립니다. SELECT * FROM posts WHERE (created_at < '2024-01-01 00:00:02') OR (created_at = '2024-01-01 00:00:02' AND id < 8) ORDER BY created_at DESC, id DESC
안녕하세요. redis에 대해 궁금한점이 있어서 문의드립니다! redis는 고객사에서 사용 허락을 받지 않는 한 사용하면 안 되나요? 추가로 비용이 들까요? 선배님이 비용이 든다고 하더라고요 저는 중복 로그인이나 조회수 관련해서 사용을 해보려고 했었는데요. 그냥 기존 방식대로 사용하라고 하시더라고요. 이런 고민 없이 개발을 해오다보니 문득 궁금해서 여쭤봤습니다!
안녕하세요 (2) LEFT JOIN 사용 방법 준수 - 오타 질문 (3:58 부근) 에서 첫 번째 SQL이 아래와 같이 써있는데요 select u.id, u.name, ua.value from user u left join user_attribute ua on ua.user_id=u.id where ua.name='address' where 조건에 ua.name 이 아니고, ua.value가 아닐까 의미적으로 맞는게 아닌가 싶어서 질문드립니다. 전체 스키마가 있는게 아니다보니 제가 오해한 걸수도 있어서, user, user_attribute 테이블 전체 스키마를 주시면 감사하겠습니다!
간단한 영화 목록 조회입니다. 총 약 10000개의 데이터가 있습니다. redis를 적용하고 조회성능이 좋아진것은 맞지만 이상하게 redis를 적용하기 전에도 같은 조회를 계속해도 조회속도가 똑같이 빨라지는 현상을 겪고있습니다. 현재 이 movie는 MSA 의 여러 서비스 중 하나입니다. 혹시 MSA 아키텍쳐 자체가 문제가 될 수도 있나요? @Cacheable(cacheNames = "getMovies", key = "'movie:all'", cacheManager = "movieCacheManager") public List<Movie> getAllMovies() { return movieRepository.findAll(); } @GetMapping("/movies") public ResponseEntity<List<MovieDto>> getAllMovies() { List<Movie> allMovies = movieService.getAllMovies(); List<MovieDto> dtos = new ArrayList<>(); for (Movie movie : allMovies) { dtos.add(new ModelMapper().map(movie, MovieDto.class)); } return ResponseEntity.status(HttpStatus.OK).body(dtos); } @Configuration @EnableCaching // Spring Boot의 캐싱 설정을 활성화 public class RedisCacheConfig { @Bean public CacheManager movieCacheManager(RedisConnectionFactory redisConnectionFactory) { RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration .defaultCacheConfig() // Redis에 Key를 저장할 때 String으로 직렬화(변환)해서 저장 .serializeKeysWith( RedisSerializationContext.SerializationPair.fromSerializer( new StringRedisSerializer())) // Redis에 Value를 저장할 때 Json으로 직렬화(변환)해서 저장 .serializeValuesWith( RedisSerializationContext.SerializationPair.fromSerializer( new GenericJackson2JsonRedisSerializer() ) ) // 데이터의 만료기간(TTL) 설정(1분) .entryTtl(Duration.ofMinutes(1L)); return RedisCacheManager .RedisCacheManagerBuilder .fromConnectionFactory(redisConnectionFactory) .cacheDefaults(redisCacheConfiguration) .build(); } } @Configuration public class RedisConfig { @Value("${spring.data.redis.host}") private String host; @Value("${spring.data.redis.port}") private int port; @Bean public LettuceConnectionFactory redisConnectionFactory() { return new LettuceConnectionFactory(new RedisStandaloneConfiguration(host, port)); } }
강사님 안녕하세요. 😁 강사님의 MySQL 성능 최적화 강의를 블로그에 정리하여 기록하고 싶은데 가능할지 여쭤보고 싶습니다. 강의 자료를 참고하여 제가 이해한대로 정리하고, 저의 실습 화면을 첨부하는 식으로 정리하려 합니다. 또한 출처를 분명히 표기하겠습니다. 다만 글의 전체적인 흐름이나 내용이 강의를 기반으로 한 것일거라.. 조심스러워 여쭙습니다. 항상 좋은 강의 제공해 주셔서 진심으로 감사드립니다.