Cache Aside 전략이 redis에 원하는 데이터가 있는지 확인 있으면 해당 데이터로 응답 없으면 db에서 조회 후 응답 + 레디스에 해당 데이터 저장 그런데 Write Around 전략에서 쓰기(조회를 제외한) 작업의 경우 redis에 반영하지 않고, DB에만 반영하는데 특정 데이터가 Cache Aside 전략에 따라 db에서 조회되어 응답 후 redis에도 해당 데이터가 저장되어 있는 상태라면, 해당 데이터를 수정하는 작업을 하게 될 경우 redis에는 반영하지 않고 db에만 반영하게 되면 만약 해당 데이터를 조회하려고 할 때 Cache Aside 전략에 의하면 가장 먼저 redis에 해당 데이터가 있는지 확인하는데 여기서 redis에 존재하니까 redis의 데이터로 응답을 해주면 db에 있는 원본 데이터는 수정되어 있으니 데이터 정합성 문제가 생기는 것 아닌가요? 감사합니다!!
varchar 타입의 경우 데이터 업데이트시 파편화가 생길 수 있다는 점을 이해했습니다! 다만, char 타입을 쓰면 좋은 경우가 문자열의 길이가 가변성이 크지 않은 경우라고 한다면 varchar의 경우에도 길이 가변성이 크지 않은 탓에 처음부터 선언해둔 길이를 벗어나지 않을 가능성이 클 거 같다는 생각이 들었습니다. 만약 주민등록번호라고 한다면 13자리니까 char(13)로 하거나 varchar(13)해도 이 자리수를 넘어가지 않을 것이고 자주 업데이트 되는 경우라고 해도 char도 그렇고 varchar도 그렇고 길이수만 잘 잡아놓으면 fragmenation 문제가 없는 것이 아닌지 궁금합니다. 그럼에도 char를 쓰는 것이 더 좋은 이유가 있을지 궁금해서 질문남깁니다!
안녕하세요, 좋은 강의 감사합니다. 제공해 주신 쿼리에 대해 질문이 있는데요, 제 생각에는 아래 쿼리가 특정 부서에서 최대 연봉을 가진 사용자를 조회하는게 아닌, 전체 부서에서 최대 연봉이 x 라고 하면, 세 부서에서 그 값이 있으면 출력하는 문인것 같은데, 제가 어느 부분에서 헷갈린 건지 알려주시면 감사하겠습니다. SELECT * FROM users WHERE salary = (SELECT MAX(salary) FROM users) AND department IN ('Sales', 'Marketing', 'IT'); SELECT MAX(salary) FROM users 는 users 테이블의 최대 salary 를 가져오는것이고, 괄호 밖의 department In (...) 은 부서 세개, 그리고 salary = (SELECT MAX ...) 와 함께 저 salary 에 해당 하는 users 가져오는 것이 아닌가요? 제가 sql 초보라 양해 해주시면 감사하겠습니다 ...
안녕하세요, 좋은 강의 감사합니다. created_at 에 index 를 걸어서 order by 와 같은 문제를 해결하는 것을 보았는데요, 데이터가 지속적으로 증가하고 밀리초 단위로 들어오는 created_at 이 있다면, 이것들을 모두 다 인덱스로 걸어도 괜찮은건가요?? 데이터가 계속 커지면 어떻게 처리하나요??
안녕하세요, 좋은 강의 제공해 주셔서 감사합니다. [실습] WHERE문에 인덱스를 걸기 vs ORDER BY문에 인덱스를 걸기 강의 에서 질문이 있습니다. 만일 created_at 과 department 가 AND 가 아닌 OR 조건이 주어지면, 데이터 엑세스가 더 많은것에 인덱스를 거는것이 좋을까요?? SELECT * FROM users WHERE created_at >= DATE_SUB(NOW(), INTERVAL 3 DAY) OR department = 'Sales' -- AND 대신 OR ORDER BY salary LIMIT 100;
제가 선생님 강의를보고 테이블에 천만개의 데이터를 넣고 인덱스를 테스트하고있었는데요, 2가지 질문이 생겼습니다. 질문 다음과 같이 익스플레인 에널라이즈를 하면 소요시간이 약 704ms 으로 나옵니다. 그런데 익스플레인 에널라이즈만 제거하고 다시 셀렉트를 하면 소요시간이 1.494로 증가하는데 단순 조회 쿼리와 익스플레인 에널라이즈 쿼리가 서로 다르게 동작해서 그런건가요? 분석때문에 에널라이즈쪽이 더 오래걸릴까 싶었는데 오히려 반대라서 왜 이런현상이 발생하는지 궁금합니다. -> Filter: ((reservation.userId = 389788) or (reservation.seatId = 50)) (cost=11192 rows=10272) (actual time=2.33..678 rows=10271 loops=1) -> Deduplicate rows sorted by row ID (cost=11192 rows=10272) (actual time=2.3..676 rows=10271 loops=1) -> Index range scan on reservation using idx_user over (userId = 389788) (cost=1.11 rows=1) (actual time=0.115..0.115 rows=0 loops=1) -> Index range scan on reservation using idx_seat over (seatId = 50) (cost=1038 rows=10271) (actual time=0.0497..2.77 rows=10271 loops=1) 질문 제가 다음과 같은 쿼리에 인덱스를 걸며 테스트해보니 복합인덱스 ( userId,seatId or reverse ) 는 전혀 인덱스를 활용하지않고 단일 인덱스를 각각 지정했을 경우에만 아래와같이 인덱스를 병합해서 사용하더라구요. 이렇게 속도를 절반으로 떨어뜨렸는데 아무래도 데이터가 천만개라 그런가 여전히 1초 이상의 시간이 소요되어서 선생님이 보셨을때 여기서 더 개선해볼 방법이 있는지 궁금합니다. where쪽을 건드려 보자니 둘중 하나라도 충족되면 가져와야하는 상황이라면 or 말고 다른건 떠오르질않았습니다. (에널라이즈는 시간이 1초 미만으로 나오지만 실제로 쿼리 돌려보면 소요시간 1.4초 이상으로 찍힙니다. ) CREATE INDEX idx_user ON reservation_entity(userId); CREATE INDEX idx_seat ON reservation_entity(seatId); SELECT `reservation`.`createdAt` AS `reservation_createdAt`, `reservation`.`updatedAt` AS `reservation_updatedAt`, `reservation`.`deletedAt` AS `reservation_deletedAt`, `reservation`.`id` AS `reservation_id`, `reservation`.`userId` AS `reservation_userId`, `reservation`.`concertId` AS `reservation_concertId`, `reservation`.`seatId` AS `reservation_seatId`, `reservation`.`status` AS `reservation_status`, `reservation`.`price` AS `reservation_price`, `reservation`.`concertName` AS `reservation_concertName`, `reservation`.`seatNumber` AS `reservation_seatNumber`, `reservation`.`openAt` AS `reservation_openAt`, `reservation`.`closeAt` AS `reservation_closeAt` FROM `reservation_entity` `reservation` WHERE `reservation`.`userId` = 389788 OR `reservation`.`seatId` = 50; -> Filter: ((reservation.userId = 389788) or (reservation.seatId = 50)) (cost=11192 rows=10272) (actual time=2.33..678 rows=10271 loops=1) -> Deduplicate rows sorted by row ID (cost=11192 rows=10272) (actual time=2.3..676 rows=10271 loops=1) -> Index range scan on reservation using idx_user over (userId = 389788) (cost=1.11 rows=1) (actual time=0.115..0.115 rows=0 loops=1) -> Index range scan on reservation using idx_seat over (seatId = 50) (cost=1038 rows=10271) (actual time=0.0497..2.77 rows=10271 loops=1)
강의를 듣다 궁금한 점이 생겨서 글을 남김니다. 보통 테이블을 생성할때 당연하게 pk를 지정해 주었는데 pk가 없는 테이블도 생성을 하나요? 생성은 되는것 같은데 똑같이 테스트를 해보니 따로 정렬한는 기준이 없어서 그런지 id 7번을 2번으로 바꿔도 들어온 순서대로 위치가 맨 마지막에 있는것을 확인했습니다. pk가 없는 테이블도 있는지 있으면 성능이라던지 차이점이 뭔지 궁금합니다.
인덱스를 생성할때, 오름차순 - 내림차순도 설정할수있는데, 날짜 기준으로 '최신 날짜 기준'으로 자주 조회하는 쿼리일 때, 인덱스를 날짜 기준으로 내림차순으로 만들면 쿼리에 더 효과가 있는 걸까요? 아니면 정렬 설정 상관없이 '옵티마이저'가 알아서 판단해서 조회를 하는 건가요?? 그리고 강의 너무 유익하게 듣고있습니다. 늘 좋은 강의 감사합니다
안녕 하세요.. 실제로 count(*) 때문에 고민이 많습니다. 게시판 형태의 화면이 있는데요.. 데이터가 약 250만건 정도 입니다. 조인된 테이블은 6개 이고요.. 테이블 6개를 조인 해서 보여주다 보니 검색 조건은 매우 많습니다. 페이징을 20개씩 10페이지씩 보여주고 있는데요.. 강의 내용 대로 전체 count(*) 때문에 속도가 느립니다. 전체 갯수를 소스 상에 써 놓고 테스트를 해보면 속도가 느리지 않거든여.. 강의를 보기 전에도 테스트 해본 결과 속도는 전체 갯수의 count(*) 문제 라고 판단 하고 있었는데요.. 시스템의 로우 갯수를 사용 하는 방법이나 리눅스의 cron 으로 각 테이블의 갯수를 10분 단위로 입력 하는 것 등.. 여러가지 생각을 해보았으나..검색 때문에 포기 했습니다. 검색을 하면 검색 결과에 대한 전체건수가 나와야 하는데.. 이건 실시간 아니면 파악할 수가 없으니까요.. 강의를 보면서 힌트를 얻고자 했으나.. 대략적인 건수.. 임의의 페이지 표기 통계 이용 대략 이해는 됩니다만.. 만일 검색을 하게 되면..모두 사용 할 수 없는 것 아닌가요? 강의 에서 얘기한 것들은 모두 아무런 조건이 없을 경우 이고.. 예를 들어 검색 조건이 10가지 정도 될 경우 어떤 조건으로 검색할 지 모르는 상황인데 대략적인 건수를 표시할 수도 없고 임의의 페이지를 표시할 수도 없습니다. 예를 들어 검색 조건 시 1개도 없는 경우도 있을 수 있는데.. 어떻게 대략적인 건수를 표시를 할 것이며.. 임의의 페이지를 표시 할 수 있을까요.. 검색결과가 1건도 나오지 않았는데 페이지를 1~10 까지 대략적으로 표시할 수는 없는 것 아닌가요? 통계이용은 검색 시 더더욱 사용할 수 없고요.. 제시하신 방법으로는 문제가 해결 될 것 같지 않은데.. 제가 잘못 생각 하고 있는 걸까요? 제 생각이 틀렸으면 좋겠습니다만.. 방법이 있을까요?
안녕하세요. 예시를 위해 테이블명을 변경했습니다. 도메인상 이해안되도 이해부탁드립니다..! 바로 질문으로 들어가면 아래에 쿼리를 발생시키면 supremum pseudo-record 락이 생기게 됩니다. 하지만 여기서 다른 세션에서 아래 쿼리를 똑같이 실행하면 select for update에서 락대기가 걸릴거라고 예상했는데 START TRANSACTION; #1 #reader_id+name 조합으로 유니크인덱스 사용중 SELECT * FROM book b WHERE reader_id = 21 AND name = 'ABC' FOR UPDATE; #2 INSERT INTO book VALUES (null, 'ABC', 21); #3 아래 처럼 같은 락이 추가됩니다. 그래서 두 세션중 어느세션에서 insert 쿼리를 입력하든 Lock 대기가 걸리게됩니다. select에서 락대기가 걸리길 바랬는데 insert를 해야 락대기가 걸리는 이유가 무엇인가요? 답변 미리 감사합니다.
안녕하세요 강사님! 실행 계획 type에 대해서 궁금한 점이 있습니다. ref가 UNIQUE가 아닌 컬럼의 인덱스를 사용한 경우라고 해주셨는데, 그러면 UNIQUE가 아닌 컬럼의 인덱스이지만 index나 range의 경우에 해당하면 해당 타입으로 표시되는 거고 저 둘(index, range)이 아닐 때, ref 타입으로 표시되는 걸까요? 그리고 한 가지 더 궁금한 점이 있는데, 만약 데이터를 조회한 결과들을 바로 View로 보내는 게 아니고 자바 코드를 사용한 계산을 통해 가공해야 하는 상황이라면 굳이 ORDER BY를 쓰지 않고, 데이터 조회 후, Collections.sort()와 같은 자바 코드로 정렬하는 편이 나을까요?
"테이블 파티셔닝이 필요한 이유"중에 "자원 사용 효율 증가 및 쿼리 성능 향상"을 언급주셨습니다. 예를들어 최근에 저장된 데이터들 위주로 조회하는 경우 파티션 프루닝을 통해 최근 데이터만 접근하니까 효율적이라는 내용인데요, 효율적인 부분이 제가 생각했을 때 아래 2가지 정도인 것 같습니다. 테이블의 모든 row를 접근 안해도 되고 더 적은 데이터만 읽어도 됨 버퍼풀에 자주 사용되는 일부 데이터만 로드해도 됨 여기서 질문이 있습니다. 파티셔닝키를 대상으로 인덱스를 걸면, 마찬가지로 최근 데이터만 접근가능하고, 버퍼풀에 최근 데이터만 올라가지 않나요? 인덱스를 거는 방식이 파티셔닝을 사용하는 것에 비해 어떤 점에서 부족한가요?
"DeadLock 예시(2)"에서 INSERT구문이 UNIQUE를 보장하기위해 shared lock을 걸고 확인한다고하였는데요, 그냥 처음부터 exclusive lock을 걸고 값을 확인하게 구현할 수도 있을 것 같은데, 그렇게 안되어있는 특별한 이유가 있을까요? exclusive lock을 건 상태에서는 값이 있는지 확인이 불가능하다 (shared lock을 걸었을때만 가능하다) 그냥 어쩌다보니 MySQL이 그렇게 구현되어있다. lock경합을 줄이기위한 의도로 이렇게 구현했다? 제가 생각나는 이유는 위 2개 정도인데, 어떤 이유인지 아실까요?
안녕하세요. 질문 드립니다. 1:N 구조의 웹 어플리케이션입니다. 종종 동일한 insert 요청이 짧은 시간에 발생 합니다. insert는 N(child) 테이블에 되어야 합니다. 해당 테이블에는 유니크 제약조건 이 걸려있어서 중복 데이터는 절대로 insert 되지 않지만 동일 요청에 의해서 DeadLock이 발생 하고 있습니다. (물론 빈도는 많지 않습니다.) 실행 순서는 이렇게 됩니다. Parent테이블의 id를 이용해서 join 쿼리로 select 합니다. (child 테이블 존재 여부 확인) child 테이블에 데이터가 존재한다면 수량 증가, 없다면 insert를 합니다. 이 때 데이터가 없는 상황에서 select-insert 요청이 서로다른 tx에서 발생할 때 데드락이 발생합니다. 이 경우 어떤 전략으로 회피할 수 있을까요? 유니크 제약 조건에 의해서 중복 데이터가 생기는건 방지되고 있고, 데드락 자체가 하루 한 건 정도 발생하고 있어서 시스템 운영상에서는 문제가 없으나 어떤 해결책이 있을지 궁금합니다.
안녕하세요. 현재 강의를 수강중인 학생입니다. RATERAL 사용 관련되어 질문이 있어 글 남겨드립니다. 잘못된 지식일 수 있지만, 서브쿼리를 사용하면 DBMS에서 지원하는 최적화를 지원받지 못해 서브쿼리를 사용하는 것보다는 최대한 조인을 사용하거나 차라리 쿼리를 나눠서 사용하는 것을 권장한다고 알고 있었습니다. 그런데 해당 강의를 수강하고 LATERAL의 사용을 적극 권장하셔서 제가 알고 있는 지식과 충돌하는 것 같습니다 혹시 어떤 경우에 LATERAL을 사용 하는 것이 좋을 지 여쭤보고자 글을 작성합니다. 감사합니다.
안녕 하세요.. 이런 질문을 드려도 될까 모르겠습니다만.. 현재 운영 되는 사이트는 ms-sql 로 bak 파일 기준 약 50기가 정도 됩니다. 사이트를 개편 하려고 하고 있는데요..mysql 로 바꾸는 것을 논의 중 입니다. 처음 부터 데이터가 50기가 가 입력 되는 것은 아니고..운영 하면서 데이터가 늘어날텐데.. 경험 상 50기가 정도 될 것으로 예상 됩니다. 특정 테이블은 몇천만건의 데이터가 입력 될 수도 있는데요.. mysql 이나 mariadb 로 이 정도의 데이터베이스를 운영 할 수 있을지.. 사이트 속도 에는 큰 문제가 없을지.. 조언 부탁 드립니다. 감사 합니다.
안녕하세요. 이제 2회차로 다시 잘 보고 있는 수강생입니다 🙂 Ep15를 보던 중 복합 인덱스의 컬럼들 중 선행컬럼을 조건에서 누락할 경우 풀 스캔이 될 수 있다고해서 직접 쿼리를 실행해봤습니다. 환경: MySQL 8.2.0 쿼리 explain select * from users where joined_at > '2022-07-24 00:00:00'; 결과 8.0.21버전부터는 인덱스 스킵 스캔을 통해 선행 컬럼이 조건에 포함되지 않아도 후속 컬럼을 이용해 인덱스 일부 활용이 가능하다고 하는데 이 때문에 위와 같은 실행 계획나 나온걸까요?