728x90

목차

     

     

    1. 튜닝 전 쿼리

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    SELECT
        A.HOST_NAME AS HOSTNAME,
        INITCAP(A.HOST_STATUS) AS HOSTSTATUS,
        AVG(A.CPU_USE_RATE) AS CPU_AVG_RATE,
        MAX(A.CPU_USE_RATE) AS CPU_MAX_RATE
    FROM (
        SELECT HOST_NAME,
               HOST_STATUS,
               100 - CPU_IDLE AS CPU_USE_RATE
        FROM TABLE_1
        WHERE TO_CHAR(COLLECTION_TIME, 'YYYYMMDDHH24MISS')
        BETWEEN TO_CHAR(TO_TIMESTAMP('202306131010''YYYYMMDDHH24MI'- INTERVAL '7 DAY''YYYYMMDDHH24MI')|| '00'
        AND '202306131010'|| '59'
    ) AS A
    GROUP BY HOST_NAME, HOST_STATUS
    cs

    2. 튜닝 후 쿼리

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    SELECT
        A.HOST_NAME AS HOSTNAME,
        INITCAP(A.HOST_STATUS) AS HOSTSTATUS,
        AVG(A.CPU_USE_RATE) AS CPU_AVG_RATE,
        MAX(A.CPU_USE_RATE) AS CPU_MAX_RATE
    FROM (
        SELECT HOST_NAME,
               HOST_STATUS,
               100 - CPU_IDLE AS CPU_USE_RATE
        FROM TABLE_1
        WHERE COLLECTION_TIME >= TO_TIMESTAMP('202206131010', 'YYYYMMDDHH24MI'- INTERVAL '7 DAY'
        AND COLLECTION_TIME <= TO_TIMESTAMP('202206131010''YYYYMMDDHH24MI')
    ) AS A
    GROUP BY HOST_NAME, HOST_STATUS
    cs

     

    두 쿼리의 차이는 '서브쿼리 테이블 A' 조건절에 between 사용 유무이다. 

    group by는 'n log n'의 시간복잡도를 가진다. 즉 row 하나씩 조회하면서 그룹화 시키는 작업을 이진탐색과 비슷한 방식으로 연산하는 것이다. group by를 사용할 땐 이미 데이터가 많을 수록 쿼리 속도가 오래걸리기 때문에 'n log n'의 시간복잡도를 유지해주는 것이 핵심이다.

     

    하지만 튜닝 전 쿼리는 between을 사용하면서 유지에 실패하였다. 이유는 between 함수의 시간복잡도는 n이기 때문이다. 우리가 대부분 알고 있듯이 index를 사용해야 쿼리속도가 빠르다는 것을 알고있다. 왜냐하면 hashmap, key & value 자료구조 처럼 O(1)의 시간복잡도를 갖게되기 때문이다. 하지만 between은 모든 row를 조회하면서 A and B 범위에 해당하는 데이터를 분류하기 때문에 O(1)이 아닌 O(n)의 시간복잡도를 갖는다.

     

    그렇기 때문에 해당 쿼리의 시간복잡도는 'n log n'이 아닌 'n log n²'이 된 것이다. 당연히 속도가 훨씬 느려질 수 밖에 없다.

    그래서 부등호를 사용하여 쿼리속도를 'n log n'으로 유지되게 처리했다.

    728x90
    TOP