요즘 부하가 걸릴정도의 트레픽을 다루는 서비스를 유지보수 하는일을 하고있다.

동접자가 6000까지 올라갈 정도로 인기? 가많은 서비스 인데 업데이트 실수가 있었다.

 

 범인은 바로 index .... 

 

쿼리 튜닝에 있어 index 는 기본중에 기본인데 오늘 새로 알았던 사실을 적어본다.

 

left join on 사용자정보.userId= 주문정보.userId

 

이런식의 조인 결과가 있었는데 

 

테이블 구조는 이렇다.

 

사용자 정보 테이블

 

주문정보

 

대충 이러한 구조인데 ... 이상한점을 금방 눈치차린 사람도 있겠지만 ... 초반에는 아무런 생각조차 못하고 있었다

 

물론 사용자테이블의 userId 는 기본키라 인덱스가 걸려있었고

주문테이블의 userId 는 인덱스 생성을 한 상태

 

당연히 인덱스끼리의 조인이라 별 문제 없을줄 알았으나 이는 slowquery 를 유발 했다

 

explain 으로도 엄청난 자원을 소모 하고 있었고 그이유는 타입 int 형과 타입 char 의 서로 상이한 타입과의 조인 이었다.

 

사용자테이블의 userId 는 int, 주문테이블의 사용자 아이디는 varchar 여서 서로 문제가 되었다.

 

이는 CAST 함수를 사용해서 해결 했다.

 

left join on CAST(사용자정보.userId AS CHAR)= 주문정보.userId

 

조인하는 한쪽을 형변환 하여 조인 하니 index 가 잘 걸리는 것을 확인 하였다.

 

cast 함수를 찾아보니

 

CAST(value AS datatype)

https://www.w3schools.com/sql/func_mysql_cast.asp

인자값은 다양하게 지원 하고 있는것을 확인 했다.

 

다음에 요기나게 사용 해볼수 있을 듯

반응형

Ehache로 추가하고 삭제하고.. 글이 참 많지만

모든 캐시들을 삭제하는 건 글이 별로 없기에 작성한다!

 

Ehcache에 대한 설명과 Config 만드는 법은 아래 글을 참고!

https://kagoon.tistory.com/56

 

spring cache 를 사용 하기 위한 ehcache 사용법

강준한 입니다. 감동을 줄 뻔한 이야기로 시작해보죠. 아들이 치매에 걸린 아버지와 같이 있습니다. 아버지는 멀리 있는 새를 보고 아들에게 물었습니다, 저게 무어냐? 아들이 말하죠... 까마귀

kagoon.tistory.com

 

Class 안에 아래 코드를 적어준다!

 

@Autowired
    private CacheConfig ehcacheManager;

    public void cacheClear () {
    
        CacheManager cacheManager = ehcacheManager.EhcacheManager();
        cacheManager.getCacheNames().forEach(cacheName -> cacheManager.getCache(cacheName).clear());
        
    }

 

그럼 만들어둔 캐싱을 하나씩 불러와 결론적으로 전체 삭제가 되는 것을 확인할 수 있다!

필자의 경우 혹시 모를 실패나 성공 여부를 확인하기 위해 cacheClaer메소드 안을 try catch로 잡았고,

String을 리턴값으로 줘 확인 가능하도록 코드를 구성했다 ㅎㅎ

반응형

뒤로가기 막는 방법이 아니라

지금 페이지가 뒤로가기로 왔는지 아는 방법을 써보려고 한다!

 

// onpageshow의 경우 page 호출되면 무조건 실행됨

window.onpageshow = function (event){

    //뒤로가기로 페이지 접근했는지 확인
    if(event.persisted || (window.performance && window.performance.navigation.type == 2)){

        //쓰고 싶은 코드
        
    }
}

 

이렇게 하면 지금 해당 페이지가 뒤로가기로 접근했는지 확인할 수 있다!

하지만 막상 코드를 입력해보면 navigation.type == 2 부분이 deprecated 되어 취소선이 그어져있는 걸 볼 수 있다.

그대로 써도 기능은 하지만 영 찝찝하다면 밑에 내용으로 쓰면 된다!

 

// onpageshow의 경우 page 호출되면 무조건 실행됨

window.onpageshow = function (event){     //뒤로가기로 페이지 접근했는지 확인
    if(event.persisted || (window.performance && window.performance.navigation.type == 2) || (window.performance.getEntriesByType("navigation")[0].type == "back_forward")){

        //쓰고 싶은 코드
        
    }
}

 

if문 안에 새롭게 window.performance.getEntriesByType("navigation")[0].type == "back_forward" 가 추가된 걸 볼 수 있다.

window.performance.getEntriesByType("navigation")[0].type은 웹페이지의 탐색유형을 반환하는 코드이고,

back_foward는 해당 페이지가 뒤로가기나 앞으로가기로 왔는지 인식해준다!

 

반응형

개발중에 작은 오류 하나에 ... 헛방을 키다 기록용으로 남겨 놓습니다.

mybatis 를 이용한 DB 쿼리 조회에서 

select 안에 join 한 다른 테이블의 리스트 형을 처리 하고자 mybatis의 collection을 이용 하고 있습니다

 

<resultMap type="testVo" id="Map">
    <id property="seq" column="seq"/>
    <result property="userId" column="userId"/>
    <result property="userPw" column="userPw" />
    <collection property="info" javaType="List" ofType="myVo">
        <result property="nameSeq" column="nameSeq"/>
        <result property="testId" column="testId"/>
    </collection>
</resultMap>

resultMap 을 사용 해야 하고 컬렉션 안에는 조인 결과가 많은 리스트로 생성 됩니다

 

실행 결과는 argument type mismatch.....

 

이는 VO 와 DB테이블과 무언가의 변수차이가 난다는 에러 이므로 저와 같은 상황에서는 

myVo 에 info 라는 변수가 존재 해야 하고 info 는 List 타입이어야 해결 됬습니다.

 

반응형

+ Recent posts